ivl 679
|
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