ivl 679
ivl/details/array/impl/specialization/force_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 namespace array_details {
00025 
00026 template <class RESIZEABLE>
00027 struct force_resize_details { };
00028 
00029 template <class HAS_C_PTR, class T>
00030 struct force_ptr_details { };
00031 
00032 } /* namespace array_details */
00033 
00043 template <class T,
00044                  class A,
00045                  class DERIVED_INFO
00046              >
00047 class array<T, data::forced<A, DERIVED_INFO> >
00048         :
00049         public array_common_base<array<T,
00050                 data::forced<A, DERIVED_INFO> > >
00051 
00052 {
00053 
00054 private:
00055         typedef array_common_base<array<T,
00056                 data::forced<A, DERIVED_INFO> > > common_base_class;
00057 
00058         typedef typename types::t_if<typename array::is_writeable,
00059                         typename types::best_iterator<A>::type,
00060                         typename A::const_iterator>::type a_best_iterator;
00061 
00062         typedef typename types::t_if<typename array::is_writeable,
00063                         typename types::best_reverse_iterator<A>::type,
00064                         typename A::const_reverse_iterator>::type a_best_reverse_iterator;
00065 
00066         typedef typename A::this_array_type a_t;
00067 
00068 protected:
00069         typedef typename array::has_random_access prv_has_random_access;
00070 
00071         typedef array_details::elem_func_tools<T,
00072                 prv_has_random_access::value> tool;
00073 
00074         friend class tool::not_a_type; // allow disabled types only in our class
00075 
00076         A* a_ptr;
00077         a_best_iterator a_begin;
00078         size_t len;
00079 
00080 public:
00081         typedef array this_type;
00082 
00083         typedef this_type this_array_type;
00084 
00085         typedef this_type array_type;
00086 
00087         typedef T elem_type;
00088 
00089         typedef typename this_type::derived_type derived_type;
00090 
00091         typedef typename common_base_class::base_class base_class;
00092 
00094         typedef size_t size_type;
00095 
00097         typedef ptrdiff_t diff_type;
00098 
00099         using base_class::derived;
00100 
00101 
00102         void resize(size_t len)
00103         {
00104                 if(array_details::force_resize_details<typename array::is_resizeable>
00105                         ::resize(a_ptr, len)) {
00106                                 a_begin = a_ptr->begin();
00107                                 len = a_ptr->length();
00108                         }
00109         }
00110 
00111         void resize(size_t len, const T& s) // with padding
00112         {
00113                 if(array_details::force_resize_details<typename array::is_resizeable>
00114                         ::resize(static_cast<a_t*>(a_ptr), len, s)) {
00115                                 a_begin = a_ptr->begin();
00116                                 len = a_ptr->length();
00117                         }
00118         }
00119 
00121         void reshape(size_t len) { resize(len); }
00122         void reshape(size_t len, const T& s) { resize(len, s); }
00123 
00124         void clear() { resize(0); }
00125 
00126         typedef typename types::t_if<typename array::is_writeable,
00127                 a_best_iterator, types::not_a_type>::type iterator;
00128 
00129         typedef typename A::const_iterator const_iterator;
00130 
00131         typedef typename types::t_if<typename array::is_writeable,
00132                 typename types::best_reverse_iterator<A>::type,
00133                 types::not_a_type>::type reverse_iterator;
00134 
00135         typedef typename A::const_reverse_iterator const_reverse_iterator;
00136 
00137         typedef typename A::iter_border_walker iter_border_walker;
00138 
00139         typedef a_best_iterator best_iterator;
00140         typedef typename std::iterator_traits<best_iterator>::reference reference;
00141         typedef typename std::iterator_traits<const_iterator>::
00142                 reference const_reference;
00143         typedef reference best_reference;
00144 
00145         best_iterator begin() { return a_begin; }
00146         best_iterator end() { return a_ptr->end(); }
00147         const_iterator begin() const { return const_iterator(a_begin); }
00148         const_iterator end() const { return a_ptr->end(); }
00149 
00150         a_best_reverse_iterator rbegin() { return a_ptr->rbegin(); }
00151         a_best_reverse_iterator rend() { return a_ptr->rend(); }
00152         const_reverse_iterator rbegin() const { return a_ptr->rbegin(); }
00153         const_reverse_iterator rend() const { return a_ptr->rend(); }
00154 
00155         typename types::apply_const<T, types::is_const<A> >::type c_ptr()
00156         {
00157                 return array_details::force_ptr_details<typename array::has_c_ptr, T>
00158                         ::c_ptr(a_ptr);
00159         }
00160 
00161         const T* c_ptr() const
00162         {
00163                 return array_details::force_ptr_details<typename array::has_c_ptr, T>
00164                         ::const_c_ptr(a_ptr);
00165         }
00166 
00169         //TODO: explain this better.
00171         size_t length() const { return len; }
00173         size_type size() const { return length(); }
00175         size_t numel() const { return length(); }
00178         iter_border_walker first_to_last() const { return a_ptr->first_to_last(); }
00179         iter_border_walker begin_to_end() const { return a_ptr->begin_to_end(); }
00180 
00186 
00187         typename best_reference operator[]
00188                 (typename tool::brackets_arg i)
00189         {
00190                 CHECK(i >= 0 && i < length(), erange);
00191                 return tool::brackets(a_begin, i);
00192         }
00193 
00195         typename const_reference operator[]
00196                 (typename tool::brackets_arg i) const
00197         {
00198                 CHECK(i >= 0 && i < length(), erange);
00199                 return tool::brackets(a_begin, i);
00200         }
00205         template <class D>
00206         bool overlap(const D& a) const { return false; }
00207 
00208         void setref(A& a)
00209         {
00210                 a_ptr = &a;
00211                 a_begin = a.begin();
00212                 len = a.length();
00213         }
00218 
00219         array() : a_ptr(0), len(0) { }
00220 
00222         array(A& a) { setref(a); }
00223 
00225         array(const array& o) { setref(*o.a_ptr); }
00231 
00232         array(size_t) {}
00233 
00235         template <class J, class D>
00236         array(size_t, const array<J, D>&) {}
00237 
00239         array(size_t, const T*) {}
00240 
00242         template<class J, class S>
00243         array(const array<J, S>& a) {}
00244 
00257         using base_class::operator=;
00258 
00259         this_type& operator=(const this_type& a)
00260         {
00261                 common_base_class::operator=(a);
00262                 return *this;
00263         }
00266 
00267         ~array() { }
00268 
00269 };
00270 
00271 namespace array_details {
00272 
00273 template <>
00274 struct force_resize_details<types::t_false>
00275 {
00276         template <class A, class S>
00277         static inline
00278         bool resize(A* a, const S& l) { return false; }
00279 
00280         template <class A, class S, class T>
00281         static inline
00282         bool resize(A* a, const S& l, const T& t) { return false; }
00283 };
00284 
00285 template <>
00286 struct force_resize_details<types::t_true>
00287 {
00288         template <class A, class S>
00289         static inline
00290         bool resize(A* a, const S& l) { a->resize(l); return true; }
00291 
00292         template <class A, class S, class T>
00293         static inline
00294         bool resize(A* a, const S& l, const T& t) { a->resize(l, t); return true; }
00295 };
00296 
00297 template <class T>
00298 struct force_ptr_details <types::t_false, T>
00299 {
00300         template <class A>
00301         static inline T* c_ptr(A* a) { return 0; }
00302         template <class A>
00303         static inline const T* c_ptr(const A* a) { return 0; }
00304 };
00305 
00306 template <class T>
00307 struct force_ptr_details <types::t_true, T>
00308 {
00309         template <class A>
00310         static inline T* c_ptr(A* a) { return a->c_ptr(); }
00311         template <class A>
00312         static inline const T* c_ptr(const A* a) { return a->c_ptr(); }
00313 };
00314 
00315 } /* namespace array_details */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations