Coverity: Core module errors fixed
[scilab.git] / scilab / modules / core / src / cpp / unrolled_algorithms.hxx
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010 - DIGITEO - Bernard HUGUENEY
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15 /*-----------------------------------------------------------------------------------*/
16 #ifndef UNROLLED_ALGORITHMS_HXX
17 #define UNROLLED_ALGORITHMS_HXX
18
19 namespace
20 {
21 /*
22  * generic template unrolling for small vectors
23  */
24
25 /**
26  * C++ does not allow function template partial specialization so eq_n<> delegates to work to a eq_n_t<> struct
27  * which implements the function in operator().
28  *
29  * @param i1 : iterator to the beginning of the first sequence
30  * @param i2 : iterator to the beginning of the second sequence
31  * @return true iff *i1 == *i2 &&...&& *(i1+N-1) == *(i2+N-1)
32  */
33 template<typename It1, typename It2, int N> struct eq_n_t
34 {
35     bool operator()(It1 i1, It2 i2) const /* generic recursive implementation */
36     {
37         return (*i1 == *i2) && eq_n_t < It1, It2, N - 1 > ()(++i1, ++i2) ;
38     }
39 };
40 template<typename It1, typename It2> struct eq_n_t<It1, It2, 0>
41 {
42     bool operator()(It1 i1, It2 i2) const /* partial specialization for N=0 */
43     {
44         return true ;
45     }
46 };
47 /**
48  * Compares two sequences for equality when the size in know at compile time.
49  * Uses template metaprogramming to ensure loop unrolling.
50  *
51  * @param i1 : iterator to the beginning of the first sequence
52  * @param i2 : iterator to the beginning of the second sequence
53  * @return true iff *i1 == *i2 &&...&& *(i1+N-1) == *(i2+N-1)
54  */
55 template<int N, typename It1, typename It2> bool eq_n(It1 i1, It2 i2)
56 {
57     return eq_n_t<It1, It2, N>()(i1, i2);
58 }
59
60 /**
61  * ensure most efficient inlining irrespectively of optimization compiler options for ids of nsiz=6 ints
62  *
63  * we make all the (4)  combinations of (const or not) arguments.
64  *
65  * @param i1 : int* beginning of the first int[6]
66  * @param i2 : int* beginning of the second int[6]
67  * @return true iff *i1 == *i2 &&...&& *(i1+5) == *(i2+5)
68  */
69 template<> bool eq_n<6, int const*, int const*>(int const* id1, int const* id2)
70 {
71     return (id1[0] == id2[0]) && (id1[1] == id2[1]) && (id1[2] == id2[2]) && (id1[3] == id2[3]) && (id1[4] == id2[4]) && (id1[5] == id2[5]);
72 }
73
74 /**
75  * See above.
76  */
77 template<> bool eq_n<6, int const*, int*>(int const* id1, int* id2)
78 {
79     return (id1[0] == id2[0]) && (id1[1] == id2[1]) && (id1[2] == id2[2]) && (id1[3] == id2[3]) && (id1[4] == id2[4]) && (id1[5] == id2[5]);
80 }
81
82 /**
83  * See above.
84  */
85 template<> bool eq_n<6, int*, int const*>(int* id1, int const* id2)
86 {
87     return (id1[0] == id2[0]) && (id1[1] == id2[1]) && (id1[2] == id2[2]) && (id1[3] == id2[3]) && (id1[4] == id2[4]) && (id1[5] == id2[5]);
88 }
89
90
91 /**
92  * See above.
93  */
94 template<> bool eq_n<6, int*, int*>(int* id1, int* id2)
95 {
96     return (id1[0] == id2[0]) && (id1[1] == id2[1]) && (id1[2] == id2[2]) && (id1[3] == id2[3]) && (id1[4] == id2[4]) && (id1[5] == id2[5]);
97 }
98
99 /**
100  * C++ does not allow function template partial specialization so less_n<> delegates to work to a less_n_t<> struct
101  * which implements the function in operator().
102  *
103  * @param i1 : iterator to the beginning of the first sequence
104  * @param i2 : iterator to the beginning of the second sequence
105  * @return true iff [i1...i1+N[ < [i2...i2+N[ in lexicographical order
106  */
107
108 template<typename It1, typename It2, int N> struct less_n_t
109 {
110     bool operator()(It1 i1, It2 i2) const /*/ generic recursive case */
111     {
112         return (*i1 < *i2) ? true : ( (*i1 > *i2) ? false : less_n_t < It1, It2, N - 1 > ()(++i1, ++i2));
113     }
114 };
115
116 template<typename It1, typename It2> struct less_n_t<It1, It2, 0>
117 {
118     bool operator()(It1 i1, It2 i2) const /* special case for empty sequences */
119     {
120         return false ;
121     }
122 };
123
124 /**
125  * Compares two sequences for lexicographical order when the size in know at compile time.
126  * Uses template metaprogramming to ensure loop unrolling.
127  *
128  * @param i1 : iterator to the beginning of the first sequence
129  * @param i2 : iterator to the beginning of the second sequence
130  * @return true iff [i1...i1+N[ < [i2...i2+N[ in lexicographical order
131  */
132 template<int N, typename It1, typename It2> bool less_n(It1 i1, It2 i2)
133 {
134     return less_n_t<It1, It2, N>()(i1, i2);
135 }
136
137 /**
138  * C++ does not allow function template partial specialization so copy_n<> delegates the work to a copy_n_t<> struct
139  * which implements the function in operator().
140  *
141  * @param i1 : iterator to the beginning of the first sequence
142  * @param i2 : iterator to the beginning of the second sequence
143  * @return i1+N
144  */
145
146 template<typename In, typename Out, int N> struct copy_n_t
147 {
148     Out operator()(In in, Out out) const /* generic case for N>0 */
149     {
150         *out = *in;
151         return copy_n_t < In, Out, N - 1 > ()(++in, ++out);
152     }
153 };
154
155 template<typename In, typename Out> struct copy_n_t<In, Out, 0>
156 {
157     Out operator()(In, Out out) const /* special case for empty sequences */
158     {
159         return out;
160     }
161 };
162
163 /**
164  * Copy one sequence to another when the size in know at compile time.
165  * Uses template metaprogramming to ensure loop unrolling.
166  *
167  * @param i1 : iterator to the beginning of the input sequence
168  * @param i2 : iterator to the beginning of the output sequence
169  * @return in+N
170  */
171 template<int N, typename In, typename Out> Out copy_n(In in, Out out)
172 {
173     return copy_n_t<In, Out, N>()(in, out);
174 }
175
176 }
177 #endif
178 /*-----------------------------------------------------------------------------------*/