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_COMMON_ARRAY_COMMON_TOOLS_HPP 00025 #define IVL_ARRAY_DETAILS_COMMON_ARRAY_COMMON_TOOLS_HPP 00026 00027 namespace ivl { 00028 namespace array_details { 00029 00030 /* 00031 classes for unary_element_functions that add 1 or subtract 1, 00032 needed for the result of the operator++(int), and operator--(int). 00033 */ 00034 template<class T, class J> 00035 struct plus1_class 00036 { 00037 typedef types::number<5> cost; 00038 static inline T elem_op(const J& elem1) { return elem1 + 1; }; 00039 }; 00040 00041 template<class T, class J> 00042 struct minus1_class 00043 { 00044 typedef types::number<5> cost; 00045 static inline T elem_op(const J& elem1) { return elem1 - 1; }; 00046 }; 00047 00048 /* 00049 initializer class for the std::vector 00050 */ 00051 template <bool HAS_RANDOM_ACCESS> 00052 struct vector_initializer 00053 { 00054 }; 00055 00056 template <> 00057 struct vector_initializer<true> 00058 { 00059 template <class T, class AR> 00060 static void operate(std::vector<T>& v, const AR& a) 00061 { 00062 v.assign(a.begin(), a.end()); 00063 } 00064 }; 00065 00066 template <> 00067 struct vector_initializer<false> 00068 { 00069 template <class T, class IT> 00070 static void loop(std::vector<T>& v, IT first, IT last) 00071 { 00072 while(first != last) { 00073 v.push_back(*first); 00074 ++first; 00075 } 00076 } 00077 00078 template <class T, class AR> 00079 static void operate(std::vector<T>& v, const AR& a) 00080 { 00081 v.reserve(a.length()); 00082 // the reason? 00083 // I was using vector<T>(begin(), end()) constructor but: 00084 // In the case of non-random-access arrays, if I use the vector way, 00085 // one loop will be made to determine the source array length for the 00086 // vector resize, and one second loop to copy the elements. 00087 // however the length is probably known at O(1) time with a.length(). 00088 // drawbacks: not that I know of, because seq_access is always faster 00089 // or equal to index based random access and, normally, faster than 00090 // seq_nd access. A small possibility that seq_nd access would be 00091 // faster and '*this' is an array_nd, and therefore loop_on after 00092 // vector resize would be faster than calling the base constructor 00093 // of the one dimensional array (in the array_nd level) seems too much 00094 // but could be investigated. Cause the flaw of this implementation 00095 // I'm using is that the preferred seq_nd access tags are ignored. 00096 // Also! if multithreading is used it wont benefit from here!! 00097 // consider elem-functions as well! So: 00098 // TODO: could fix this to use something clever. 00099 // take care because the solution: 00100 // 00101 // vector<T>.resize() 00102 // wrap vector with iter_array x; 00103 // loop_on(x, a); 00104 // 00105 // has a cpu leak on resize cause resize uses default value that is 00106 // T() 00107 // so it will initialize all elements! 00108 // investigate this as well! (and see if it is true). 00109 // 00110 // another long solution would be to write a custom loop 00111 // (or a few custom loops, for nd etc), for the array situation 00112 // 00113 // or even a "deceiptful" vector iterator that uses push back on 00114 // the vector. bah....... 00115 // 00116 // take examples always using weird situations like array<array<T> > 00117 // 00118 // 00119 // 00120 loop(v, a.begin(), a.end()); 00121 } 00122 }; 00123 00124 } /* namespace array_details */ 00125 } /* namespace ivl */ 00126 00127 #endif // IVL_ARRAY_DETAILS_COMMON_ARRAY_COMMON_TOOLS_HPP