ivl 679
ivl/details/array/impl/common/array_common_tools.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_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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations