ivl 679
ivl/details/array/impl/iterator/extended_traits.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_ITERATOR_EXTENDED_TRAITS_HPP
00025 #define IVL_ARRAY_DETAILS_ITERATOR_EXTENDED_TRAITS_HPP
00026 
00027 namespace ivl {
00028 namespace data {
00029 
00030 namespace data_details {
00031 
00032 template <class IT>
00033 struct is_vector_iterator
00034 {
00035         typedef typename std::iterator_traits<IT>::value_type v;
00036         typedef typename types::t_or<
00037                 types::t_eq<IT, typename std::vector<v>::iterator>,
00038                 types::t_eq<IT, typename std::vector<v>::const_iterator> >::type type;
00039 };
00040 
00041 template <class IT, class HAS_BORDER_WALKER>
00042 struct border_walker_details
00043 {
00044         typedef ptrdiff_t iter_border_walker;
00045         static inline iter_border_walker from(const IT& a, const IT& b)
00046         {
00047                 return b - a;
00048         }
00049 };
00050 
00051 template <class IT>
00052 struct border_walker_details<IT, types::t_true>
00053 {
00054         typedef typename IT::iter_border_walker iter_border_walker;
00055         static inline iter_border_walker from(const IT& a, const IT& b)
00056         {
00057                 return iter_border_walker(a, b);
00058         }
00059 };
00060 
00061 template <class IT, class HAS_BORDER_WALKER>
00062 struct nd_border_walker_details
00063 {
00064         typedef ptrdiff_t iter_nd_border_walker;
00065         static inline iter_nd_border_walker from(const IT& a, const IT& b)
00066         {
00067                 return b - a;
00068         }
00069 };
00070 
00071 template <class IT>
00072 struct nd_border_walker_details<IT, types::t_true>
00073 {
00074         typedef typename IT::iter_nd_border_walker iter_nd_border_walker;
00075         static inline iter_nd_border_walker from(const IT& a, const IT& b)
00076         {
00077                 return iter_nd_border_walker(a, b);
00078         }
00079 };
00080 
00081 } /* namespace data_details */
00082 
00083 template <class IT>
00084 struct iterator_extended_traits_bw
00085 {
00086         typedef typename types::bare_type<IT>::type it;
00087 
00088         // border walker types
00089 
00090         // iterator nd's shouldn't have the border_walker tag
00091         // no_border_walker_iterator_identifier is a tag to explicitly
00092         // disable the inherited border walker for that reason.
00093         typedef typename
00094                 types::t_and_3<
00095                         types::t_not<
00096                                 types::is_base<types::no_border_walker_iterator_identifier, it>
00097                         >,
00098                         types::t_not<
00099                                 types::is_base<types::nd_border_walker_iterator_identifier, it>
00100                         >,
00101                         types::is_base<types::border_walker_iterator_identifier, it>
00102                 >::type has_border_walker;
00103 
00104         typedef typename
00105                 data_details::border_walker_details<it, has_border_walker>
00106                         ::iter_border_walker iter_border_walker;
00107 
00108         static inline
00109         iter_border_walker get_iter_border_walker(const it& a, const it& b)
00110         {
00111                 return data_details::border_walker_details<it, has_border_walker>
00112                         ::from(a, b);
00113         }
00114 
00115         typedef typename
00116                 types::is_base<types::nd_border_walker_iterator_identifier, it>
00117                         ::type has_nd_border_walker;
00118 
00119         typedef typename
00120                 data_details::nd_border_walker_details<it, has_nd_border_walker>
00121                         ::iter_nd_border_walker iter_nd_border_walker;
00122 
00123         static inline
00124         iter_nd_border_walker get_iter_nd_border_walker(const it& a, const it& b)
00125         {
00126                 return data_details::nd_border_walker_details<it, has_nd_border_walker>
00127                         ::from(a, b);
00128         }
00129 };
00130 
00131 template <class IT>
00132 struct iterator_extended_traits
00133 : public iterator_extended_traits_bw<IT>
00134 {
00135         typedef typename types::bare_type<IT>::type it;
00136         typedef typename types::t_or_3<
00137                 data_details::is_vector_iterator<it>,
00138                 types::is_base<types::pointer_based_iterator_identifier, it>,
00139                 types::is_base<types::pointer_range_based_iterator_identifier, it> >
00140                         ::type is_pointer_based;
00141 
00142         // pointer_capable is the same as pointer_based with a small difference:
00143         // we are not always capable to get pointers from vector iterators, since
00144         // some times they are not dereferencable.
00145         // pointer_capable means that you can always do &(*it) to get a pointer.
00146         typedef typename types::t_or<
00147                 types::is_base<types::pointer_based_iterator_identifier, it>,
00148                 types::is_base<types::pointer_range_based_iterator_identifier, it> >
00149                         ::type is_pointer_capable;
00150 
00151         typedef typename
00152                 types::is_base<types::pointer_range_based_iterator_identifier, it>
00153                         ::type is_pointer_range_based;
00154 
00155         typedef typename
00156                 types::t_and<is_pointer_based, types::t_not<is_pointer_range_based> >
00157                         ::type is_pointer_based_and_contiguous;
00158 
00159         typedef typename
00160                 types::is_base<types::ivl_array_reference_based_iterator_identifier, it>
00161                         ::type is_array_reference_based;
00162 
00163         typedef typename
00164                 types::is_base<types::past_end_capable_iterator_identifier, it>
00165                         ::type is_past_end_capable;
00166 };
00167 
00168 template <class IT>
00169 struct iterator_extended_traits<IT*>
00170 : public iterator_extended_traits_bw<IT*>
00171 {
00172         typedef types::t_true is_pointer_based;
00173         typedef types::t_true is_pointer_capable;
00174         typedef types::t_false is_pointer_range_based;
00175         typedef types::t_true is_pointer_based_and_contiguous;
00176         typedef types::t_false is_array_reference_based;
00177         typedef types::t_true is_past_end_capable;
00178 };
00179 
00180 } /* namespace data */
00181 } /* namespace ivl */
00182 
00183 #endif // IVL_ARRAY_DETAILS_ITERATOR_EXTENDED_TRAITS_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations