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_ARRAY_HPP 00025 #define IVL_ARRAY_DETAILS_ARRAY_HPP 00026 00027 namespace ivl { 00028 00029 #include "specialization/array_class.hpp" 00030 00031 #include "specialization/empty_class.hpp" 00032 00033 #include "specialization/little_class.hpp" 00034 00035 #include "specialization/ref_iterator_class.hpp" 00036 00037 #include "specialization/range_class.hpp" 00038 00039 #include "specialization/val_repeat_class.hpp" 00040 00041 #include "specialization/ref_val_repeat_class.hpp" 00042 00043 #include "specialization/fixed_val_repeat_class.hpp" 00044 00045 #include "specialization/fixed_class.hpp" 00046 00047 #include "specialization/binary_elem_func_ptr_class.hpp" 00048 00049 #include "specialization/binary_elem_func_class.hpp" 00050 00051 #include "specialization/unary_elem_func_class.hpp" 00052 00053 #include "specialization/row_elem_func_class_2d.hpp" 00054 00055 #include "specialization/row_elem_func_class_nd.hpp" 00056 00057 //#include "specialization/force_class.hpp" 00058 #include "specialization/wrap_array_class.hpp" 00059 00060 #include "specialization/member_class.hpp" 00061 00062 #include "specialization/mask_class.hpp" 00063 00064 #include "specialization/indirect_class.hpp" 00065 00066 #include "specialization/slice_class.hpp" 00067 00068 #include "specialization/subarray_class.hpp" 00069 00070 #include "specialization/catarray_class.hpp" 00071 00072 00073 //-------------------------------------------------------------- 00074 // array MEMBER FUNCTIONS 00075 00076 00078 /* 00079 template<class T> 00080 std::ostream& print(std::ostream& os, 00081 const array<T, data::normal, types::term>& in); 00082 */ 00083 00084 namespace array_details { 00085 00086 // forward declaration for casting recursivity. 00087 /* 00088 template <class TO, class FROM> class elem_cast; 00089 00090 template <class S, class T, class D, class P> 00091 struct cast 00092 { 00093 typedef typename types::to_type<S, array<T, D, P> >::type 00094 ::create_similar return_type; 00095 }; 00096 */ 00097 00098 } /* namespace array_details */ 00099 00100 template <class T, class S, class J, class D> 00101 void copy(array<T, S>& out, const array<J, D>& in) 00102 { 00103 CHECK(out.length() == in.length(), erange); 00104 loops::loop<loops::assign_copy_class<T&, const J&> >( 00105 out.derived(), in.derived()); 00106 } 00107 00108 template <class T, class S, class J, class D> 00109 void copy_out(array<T, S>& out, const array<J, D>& in) 00110 { 00111 CHECK(out.length() <= in.length(), erange); 00112 typename array<J, D>::const_iterator it_src = in.begin(); 00113 typename array<T, S>::iterator it_end = out.end(); 00114 typename array<T, S>::iterator it = out.begin(); 00115 00116 while (it != it_end) *it++ = *it_src++; 00117 } 00118 00119 template <class T, class S, class J, class D> 00120 void copy_n(array<T, S>& out, const array<J, D>& in, int n) 00121 { 00122 /* TODO: would be nice 00123 CHECK(out.length() <= in.length(), erange); 00124 loops::loop_n<loops::assign_copy_class<T, J> > 00125 (out.derived(), in.derived(), n); 00126 */ 00127 typename array<J, D>::const_iterator it_src = in.begin(); 00128 typename array<T, S>::iterator it = out.begin(); 00129 00130 while (n--) *it++ = *it_src++; 00131 } 00132 00133 template <class T, class S, class J> 00134 void copy(array<T, S>& out, const J* it_src) 00135 { 00136 CHECK(it_src != NULL, einvalid); 00137 00138 typename array<T, S>::iterator it_end = out.end(); 00139 typename array<T, S>::iterator it = out.begin(); 00140 00141 while (it != it_end) 00142 *it++ = cast<T>(*it_src++); 00143 } 00144 00145 template <class T, class S> 00146 void copy(array<T, S>& out, const T& val, 00147 types::term as_element) 00148 { 00149 typename array<T, S>::iterator it_end = out.end(); 00150 typename array<T, S>::iterator it = out.begin(); 00151 00152 while (it != it_end) 00153 *(it++) = (val); 00154 } 00155 00156 template <class T, class D> 00157 std::ostream& print(std::ostream&, const array<T, D>&); 00158 00159 00160 template<class T> 00161 inline 00162 void elem_print(std::ostream& os, const T& val) 00163 { 00164 os << val << " "; 00165 } 00166 00167 00168 template<> 00169 inline 00170 void elem_print<float>(std::ostream& os, const float& val) 00171 { 00172 os << std::setw(11); 00173 if(math::ivl_isnan(val)) 00174 os << "NaN"; 00175 else if(!math::ivl_finite(val)) 00176 os << "Inf"; 00177 else 00178 os << val; 00179 os << " "; 00180 } 00181 00182 template<> 00183 inline 00184 void elem_print<double>(std::ostream& os, const double& val) 00185 { 00186 os << std::setw(11); 00187 if(math::ivl_isnan(val)) 00188 os << "NaN"; 00189 else if(!math::ivl_finite(val)) 00190 os << "Inf"; 00191 else 00192 os << val; 00193 os << " "; 00194 } 00195 00196 00197 00198 namespace array_details { 00199 00200 template <class T> 00201 struct print_init 00202 { 00203 print_init(std::ostream& os) {} 00204 }; 00205 00206 template<> 00207 struct print_init<float> 00208 { 00209 std::ostream& os; 00210 std::ios::fmtflags saveflags; 00211 print_init(std::ostream& os) : os(os), saveflags(os.flags()) 00212 { 00213 os << std::fixed << std::setprecision(4); 00214 } 00215 ~print_init() 00216 { 00217 os.flags(saveflags); 00218 } 00219 }; 00220 00221 template<> 00222 struct print_init<double> 00223 { 00224 std::ostream& os; 00225 std::ios::fmtflags saveflags; 00226 print_init(std::ostream& os) : os(os), saveflags(os.flags()) 00227 { 00228 os << std::fixed << std::setprecision(4); 00229 } 00230 ~print_init() 00231 { 00232 os.flags(saveflags); 00233 } 00234 }; 00235 00236 } /* namespace array_details */ 00237 00238 00239 template <class T, class S> 00240 std::ostream& print(std::ostream& os, const ivl::array<T, S>& in) 00241 { 00242 array_details::print_init<T> init(os); 00243 00244 os << "[ " ; 00245 for(typename ivl::array<T, S>::const_iterator it = in.begin(); 00246 it != in.end(); it++) { 00247 elem_print(os, *it); 00248 } 00249 os << "]"; 00250 00251 return os; 00252 } 00253 00254 00255 } // namespace ivl 00256 00257 #endif // IVL_ARRAY_DETAILS_ARRAY_HPP