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_CORE_DETAILS_IVL_FUNC_IVL_FUNC_HPP 00025 #define IVL_CORE_DETAILS_IVL_FUNC_IVL_FUNC_HPP 00026 00027 namespace ivl { 00028 00029 namespace convert { 00030 00031 struct dd { }; 00032 struct dl { }; 00033 struct df { }; 00034 struct ff { }; 00035 00036 struct convd { }; 00037 struct convl { }; 00038 struct convf { }; 00039 00040 template<class C> struct get_out { typedef convd type; }; 00041 template<> struct get_out<ff> { typedef convf type; }; 00042 00043 } /* namespace convert */ 00044 00045 template <class IMPL, class TPL, class OUTCONV> 00046 struct ivl_func_rvalue 00047 : 00048 public internal::tuple_rvalue<ivl_func_rvalue<IMPL, TPL, OUTCONV> > 00049 { 00050 //const TPL& 00051 TPL tpl; 00052 typedef typename types::bare_type<TPL>::type tp; 00053 00054 /* 00055 template<class T> 00056 ivl_func_rvalue(const T& t) : tpl(t) { } 00057 */ 00058 ivl_func_rvalue(TPL ts) : tpl(ts) { } 00059 00060 ivl_func_rvalue( 00061 typename tp::t1 v1 = types::skip(), 00062 typename tp::t2 v2 = types::skip(), 00063 typename tp::t3 v3 = types::skip(), 00064 typename tp::t4 v4 = types::skip(), 00065 typename tp::t5 v5 = types::skip(), 00066 typename tp::t6 v6 = types::skip(), 00067 typename tp::t7 v7 = types::skip(), 00068 typename tp::t8 v8 = types::skip(), 00069 typename tp::t9 v9 = types::skip(), 00070 typename tp::t10 v10 = types::skip()) 00071 : tpl(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) 00072 {} 00073 00074 template <class TUP> 00075 inline 00076 void tuple_output(TUP& tup) const 00077 { 00078 IMPL imp; 00079 internal::apply_tuple(internal::tplsjoin(tup, tpl), imp); 00080 } 00081 00082 template <class TUP> 00083 inline 00084 void tuple_output(const TUP& tup) const 00085 { 00086 IMPL imp; 00087 //imp.t_operate(internal::tplsjoin(tup, tpl)); 00088 internal::apply_tuple(internal::tplsjoin(tup, tpl), imp); 00089 } 00090 /* 00091 ivl_func_rvalue(const ivl_func_rvalue& oo) :tpl(oo.tpl) 00092 { 00093 std::cout << "ACOPY!!!!!!!!!!!!!!!!!!\n"; 00094 } 00095 */ 00096 //TODO:necessary? 00097 /* 00098 template <class T1> 00099 inline 00100 void output(T1& t1) const 00101 { 00102 IMPL imp; 00103 imp.t_operate(internal::tplsjoin( 00104 internal::reftpl(t1), tpl)); 00105 } 00106 00107 template <class T1, class T2> 00108 inline 00109 void output(T1& t1, T2& t2) const 00110 { 00111 IMPL imp; 00112 imp.t_operate(internal::tplsjoin( 00113 internal::reftpl(t1, t2), tpl)); 00114 } 00115 00116 template <class T1, class T2, class T3> 00117 inline 00118 void output(T1& t1, T2& t2, T3& t3) const 00119 { 00120 IMPL imp; 00121 imp.t_operate(internal::tplsjoin( 00122 internal::reftpl(t1, t2, t3), tpl)); 00123 } 00124 00125 template <class T1, class T2, class T3, class T4> 00126 inline 00127 void output(T1& t1, T2& t2, T3& t3, T4& t4) const 00128 { 00129 IMPL imp; 00130 imp.t_operate(internal::tplsjoin( 00131 internal::reftpl(t1, t2, t3, t4), tpl)); 00132 } 00133 00134 template <class T1, class T2, class T3, class T4, class T5> 00135 inline 00136 void output(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) const 00137 { 00138 IMPL imp; 00139 imp.t_operate(internal::tplsjoin( 00140 internal::reftpl(t1, t2, t3, t4, t5), tpl)); 00141 } 00142 00143 template <class T1, class T2, class T3, class T4, class T5, class T6> 00144 inline 00145 void output(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6) const 00146 { 00147 IMPL imp; 00148 imp.t_operate(internal::tplsjoin( 00149 internal::reftpl(t1, t2, t3, t4, t5, t6), tpl)); 00150 } 00151 00152 template <class T1, class T2, class T3, class T4, class T5, class T6, 00153 class T7> 00154 inline 00155 void output(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7) const 00156 { 00157 IMPL imp; 00158 imp.t_operate(internal::tplsjoin( 00159 internal::reftpl(t1, t2, t3, t4, t5, t6, t7), tpl)); 00160 } 00161 */ 00162 00163 }; 00164 00165 // ---- 00166 00167 template <class IMPL, class CONV> 00168 struct ivl_func_lcall 00169 { 00170 template<class TPL> 00171 inline 00172 ivl_func_rvalue<IMPL, const TPL&, 00173 typename convert::get_out<CONV>::type> 00174 operator[](const TPL& t) { return t; } 00175 00176 00177 00178 00179 inline 00180 ivl_func_rvalue<IMPL, 00181 internal::tuple<>, 00182 typename convert::get_out<CONV>::type> 00183 operator()() 00184 { 00185 return internal::tuple<>(); 00186 } 00187 00188 template<class T1> 00189 inline 00190 ivl_func_rvalue<IMPL, 00191 internal::tuple<const T1&>, 00192 typename convert::get_out<CONV>::type> 00193 operator()(const T1& t1) 00194 { 00195 return ivl_func_rvalue<IMPL, 00196 internal::tuple<const T1&>, 00197 typename convert::get_out<CONV>::type>(t1); 00198 } 00199 00200 template<class T1, class T2> 00201 inline 00202 ivl_func_rvalue<IMPL, 00203 internal::tuple<const T1&, const T2&>, 00204 typename convert::get_out<CONV>::type> 00205 operator()(const T1& t1, const T2& t2) 00206 { 00207 return ivl_func_rvalue<IMPL, 00208 internal::tuple<const T1&, const T2&>, 00209 typename convert::get_out<CONV>::type>(t1, t2); 00210 } 00211 00212 template<class T1, class T2, class T3> 00213 inline 00214 ivl_func_rvalue<IMPL, 00215 internal::tuple<const T1&, const T2&, const T3&>, 00216 typename convert::get_out<CONV>::type> 00217 operator()(const T1& t1, const T2& t2, const T3& t3) 00218 { 00219 return ivl_func_rvalue<IMPL, 00220 internal::tuple<const T1&, const T2&, const T3&>, 00221 typename convert::get_out<CONV>::type>(t1, t2, t3); 00222 } 00223 00224 template<class T1, class T2, class T3, class T4> 00225 inline 00226 ivl_func_rvalue<IMPL, 00227 internal::tuple<const T1&, const T2&, const T3&, const T4&>, 00228 typename convert::get_out<CONV>::type> 00229 operator()(const T1& t1, const T2& t2, const T3& t3, const T4& t4) 00230 { 00231 return ivl_func_rvalue<IMPL, 00232 internal::tuple<const T1&, const T2&, const T3&, const T4&>, 00233 typename convert::get_out<CONV>::type>(t1, t2, t3, t4); 00234 } 00235 00236 template<class T1, class T2, class T3, class T4, class T5> 00237 inline 00238 ivl_func_rvalue<IMPL, 00239 internal::tuple<const T1&, const T2&, const T3&, const T4&, 00240 const T5&>, 00241 typename convert::get_out<CONV>::type> 00242 operator()(const T1& t1, const T2& t2, const T3& t3, const T4& t4, 00243 const T5& t5) 00244 { 00245 return ivl_func_rvalue<IMPL, 00246 internal::tuple<const T1&, const T2&, const T3&, const T4&, 00247 const T5&>, 00248 typename convert::get_out<CONV>::type>(t1, t2, t3, t4, t5); 00249 } 00250 00251 template<class T1, class T2, class T3, class T4, class T5, class T6> 00252 inline 00253 ivl_func_rvalue<IMPL, 00254 internal::tuple<const T1&, const T2&, const T3&, const T4&, 00255 const T5&, const T6&>, 00256 typename convert::get_out<CONV>::type> 00257 operator()(const T1& t1, const T2& t2, const T3& t3, const T4& t4, 00258 const T5& t5, const T6& t6) 00259 { 00260 return ivl_func_rvalue<IMPL, 00261 internal::tuple<const T1&, const T2&, const T3&, const T4&, 00262 const T5&, const T6&>, 00263 typename convert::get_out<CONV>::type>(t1, t2, t3, t4, t5, t6); 00264 } 00265 00266 template<class T1, class T2, class T3, class T4, class T5, class T6, 00267 class T7> 00268 inline 00269 ivl_func_rvalue<IMPL, 00270 internal::tuple<const T1&, const T2&, const T3&, const T4&, 00271 const T5&, const T6&, const T7&>, 00272 typename convert::get_out<CONV>::type> 00273 operator()(const T1& t1, const T2& t2, const T3& t3, const T4& t4, 00274 const T5& t5, const T6& t6, const T7& t7) 00275 { 00276 return ivl_func_rvalue<IMPL, 00277 internal::tuple<const T1&, const T2&, const T3&, const T4&, 00278 const T5&, const T6&, const T7&>, 00279 typename convert::get_out<CONV>::type>(t1, t2, t3, t4, t5, t6, t7); 00280 } 00281 00282 00283 /* 00284 inline 00285 ivl_func_rvalue<IMPL, 00286 internal::tuple<>, 00287 typename convert::get_out<CONV>::type> 00288 operator()() 00289 { 00290 return internal::tuple<>(); 00291 } 00292 00293 template<class T1> 00294 inline 00295 ivl_func_rvalue<IMPL, 00296 internal::tuple<const T1&>, 00297 typename convert::get_out<CONV>::type> 00298 operator()(const T1& t1) 00299 { 00300 return internal::reftpl(t1); 00301 } 00302 00303 template<class T1, class T2> 00304 inline 00305 ivl_func_rvalue<IMPL, 00306 internal::tuple<const T1&, const T2&>, 00307 typename convert::get_out<CONV>::type> 00308 operator()(const T1& t1, const T2& t2) 00309 { 00310 return internal::reftpl(t1, t2); 00311 } 00312 00313 template<class T1, class T2, class T3> 00314 inline 00315 ivl_func_rvalue<IMPL, 00316 internal::tuple<const T1&, const T2&, const T3&>, 00317 typename convert::get_out<CONV>::type> 00318 operator()(const T1& t1, const T2& t2, const T3& t3) 00319 { 00320 return internal::reftpl(t1, t2, t3); 00321 } 00322 00323 template<class T1, class T2, class T3, class T4> 00324 inline 00325 ivl_func_rvalue<IMPL, 00326 internal::tuple<const T1&, const T2&, const T3&, const T4&>, 00327 typename convert::get_out<CONV>::type> 00328 operator()(const T1& t1, const T2& t2, const T3& t3, const T4& t4) 00329 { 00330 return internal::reftpl(t1, t2, t3, t4); 00331 } 00332 00333 template<class T1, class T2, class T3, class T4, class T5> 00334 inline 00335 ivl_func_rvalue<IMPL, 00336 internal::tuple<const T1&, const T2&, const T3&, const T4&, 00337 const T5&>, 00338 typename convert::get_out<CONV>::type> 00339 operator()(const T1& t1, const T2& t2, const T3& t3, const T4& t4, 00340 const T5& t5) 00341 { 00342 return internal::reftpl(t1, t2, t3, t4, t5); 00343 } 00344 00345 template<class T1, class T2, class T3, class T4, class T5, class T6> 00346 inline 00347 ivl_func_rvalue<IMPL, 00348 internal::tuple<const T1&, const T2&, const T3&, const T4&, 00349 const T5&, const T6&>, 00350 typename convert::get_out<CONV>::type> 00351 operator()(const T1& t1, const T2& t2, const T3& t3, const T4& t4, 00352 const T5& t5, const T6& t6) 00353 { 00354 return internal::reftpl(t1, t2, t3, t4, t5, t6); 00355 } 00356 00357 template<class T1, class T2, class T3, class T4, class T5, class T6, 00358 class T7> 00359 inline 00360 ivl_func_rvalue<IMPL, 00361 internal::tuple<const T1&, const T2&, const T3&, const T4&, 00362 const T5&, const T6&, const T7&>, 00363 typename convert::get_out<CONV>::type> 00364 operator()(const T1& t1, const T2& t2, const T3& t3, const T4& t4, 00365 const T5& t5, const T6& t6, const T7& t7) 00366 { 00367 return internal::reftpl(t1, t2, t3, t4, t5, t6, t7); 00368 } 00369 */ 00370 }; 00371 00372 // ---- 00373 00374 template <class DERIVED, class CONV = convert::ff> 00375 struct ivl_func 00376 { 00377 private: 00378 DERIVED& derived() { return static_cast<DERIVED&>(*this); } 00379 public: 00380 typedef ivl_func_lcall<DERIVED, CONV> lcall_type; 00381 00382 lcall_type operator++(int) { return lcall_type(); } 00383 00384 /* 00385 //TODO: necessary? 00386 template<int N, class T> 00387 inline void t_operate(const internal::tuple_base<N, T>& tpl) 00388 { 00389 //TODO: fix 00390 //the fix should probably be in the tuple value access. 00391 //if any fix. 00392 //otherwise, construct a tuple object when passing here 00393 //and get an actual reference. 00394 //other option, skip this part anyway to also avoid using. 00395 T& t(const_cast<T&>(tpl.derived())); 00396 internal::apply_tuple(t, derived()); 00397 } 00398 */ 00399 /* 00400 template<class T> 00401 inline void operate(internal::tuple_base<1, T> tpl) 00402 { 00403 T& t(tpl.derived()); 00404 derived().operate(t.v1); 00405 } 00406 00407 template<class T> 00408 inline void operate(internal::tuple_base<2, T> tpl) 00409 { 00410 T& t(tpl.derived()); 00411 derived().operate(t.v1, t.v2); 00412 } 00413 00414 template<class T> 00415 inline void operate(internal::tuple_base<3, T> tpl) 00416 { 00417 T& t(tpl.derived()); 00418 derived().operate(t.v1, t.v2, t.v3); 00419 } 00420 00421 template<class T> 00422 inline void operate(internal::tuple_base<4, T> tpl) 00423 { 00424 T& t(tpl.derived()); 00425 derived().operate(t.v1, t.v2, t.v3, t.v4); 00426 } 00427 00428 template<class T> 00429 inline void operate(internal::tuple_base<5, T> tpl) 00430 { 00431 T& t(tpl.derived()); 00432 derived().operate(t.v1, t.v2, t.v3, t.v4, t.v5); 00433 } 00434 00435 template<class T> 00436 inline void operate(internal::tuple_base<6, T> tpl) 00437 { 00438 T& t(tpl.derived()); 00439 derived().operate(t.v1, t.v2, t.v3, t.v4, t.v5, t.v6); 00440 } 00441 00442 template<class T> 00443 inline void operate(internal::tuple_base<7, T> tpl) 00444 { 00445 T& t(tpl.derived()); 00446 derived().operate(t.v1, t.v2, t.v3, t.v4, t.v5, t.v6, t.v7); 00447 } 00448 00449 template<class T> 00450 inline void operate(internal::tuple_base<8, T> tpl) 00451 { 00452 T& t(tpl.derived()); 00453 derived().operate(t.v1, t.v2, t.v3, t.v4, t.v5, t.v6, t.v7, t.v8); 00454 } 00455 00456 template<class T> 00457 inline void operate(internal::tuple_base<9, T> tpl) 00458 { 00459 T& t(tpl.derived()); 00460 derived().operate(t.v1, t.v2, t.v3, t.v4, t.v5, t.v6, t.v7, t.v8, t.v9); 00461 } 00462 00463 template<class T> 00464 inline void operate(internal::tuple_base<10, T> tpl) 00465 { 00466 T& t(tpl.derived()); 00467 derived().operate(t.v1, t.v2, t.v3, t.v4, t.v5, t.v6, t.v7, t.v8, t.v9, 00468 t.v10); 00469 } 00470 */ 00471 // --------------------------------------------------------------------- 00472 00473 template <class RT, class T1> 00474 RT simple(const T1& t1) 00475 { 00476 RT r = derived()++(t1); 00477 return r; 00478 } 00479 00480 template <class RT, class T1, class T2> 00481 RT simple(const T1& t1, const T2& t2) 00482 { 00483 RT r = derived()++(t1, t2); 00484 return r; 00485 } 00486 00487 template <class RT, class T1, class T2, class T3> 00488 RT simple(const T1& t1, const T2& t2, const T3& t3) 00489 { 00490 RT r = derived()++(t1, t2, t3); 00491 return r; 00492 } 00493 00494 template <class RT, class T1, class T2, class T3, class T4> 00495 RT simple(const T1& t1, const T2& t2, const T3& t3, const T4& t4) 00496 { 00497 RT r = derived()++(t1, t2, t3, t4); 00498 return r; 00499 } 00500 00501 template <class RT, class T1, class T2, class T3, class T4, 00502 class T5> 00503 RT simple(const T1& t1, const T2& t2, const T3& t3, const T4& t4, 00504 const T5& t5) 00505 { 00506 RT r = derived()++(t1, t2, t3, t4, t5); 00507 return r; 00508 } 00509 00510 template <class RT, class T1, class T2, class T3, class T4, 00511 class T5, class T6> 00512 RT simple(const T1& t1, const T2& t2, const T3& t3, const T4& t4, 00513 const T5& t5, const T6& t6) 00514 { 00515 RT r = derived()++(t1, t2, t3, t4, t5, t6); 00516 return r; 00517 } 00518 00519 template <class RT, class T1, class T2, class T3, class T4, 00520 class T5, class T6, class T7> 00521 RT simple(const T1& t1, const T2& t2, const T3& t3, const T4& t4, 00522 const T5& t5, const T6& t6, const T7& t7) 00523 { 00524 RT r = derived()++(t1, t2, t3, t4, t5, t6, t7); 00525 return r; 00526 } 00527 00528 // --------------------------------------------------------------------- 00529 00530 template < 00531 class R1, class R2 = types::skip, class R3 = types::skip, 00532 class R4 = types::skip, class R5 = types::skip, class R6 = types::skip, 00533 class R7 = types::skip, class R8 = types::skip, class R9 = types::skip, 00534 class R10 = types::skip> 00535 struct call 00536 : 00537 public ret<R1, R2, R3, R4, R5, R6, R7, R8, R9, R10> 00538 { 00539 template<class T1> 00540 call(T1& t1) 00541 { 00542 DERIVED()++(t1).tuple_output(*this); 00543 } 00544 template<class T1, class T2> 00545 call(T1& t1, T2& t2) 00546 { 00547 DERIVED()++(t1, t2).tuple_output(*this); 00548 } 00549 template<class T1, class T2, class T3> 00550 call(T1& t1, T2& t2, T3& t3) 00551 { 00552 DERIVED()++(t1, t2, t3).tuple_output(*this); 00553 } 00554 }; 00555 }; 00556 00557 template <class DERIVED, class CONV> 00558 template <class R1> 00559 struct ivl_func<DERIVED, CONV>::call<R1, types::skip, types::skip, types::skip, 00560 types::skip, types::skip, types::skip, types::skip, types::skip, 00561 types::skip> 00562 : 00563 public ret<R1> 00564 { 00565 ret<R1>& r() { return static_cast<ret<R1>&>(*this); } 00566 00567 template<class T1> 00568 call(T1& t1) 00569 { 00570 //Note: old was: DERIVED()++(t1).output(r()) 00571 DERIVED()++(t1).tuple_output(internal::reftpl(r())); 00572 } 00573 template<class T1, class T2> 00574 call(T1& t1, T2& t2) 00575 { 00576 DERIVED()++(t1, t2).tuple_output(internal::reftpl(r())); 00577 } 00578 template<class T1, class T2, class T3> 00579 call(T1& t1, T2& t2, T3& t3) 00580 { 00581 DERIVED()++(t1, t2, t3).tuple_output(internal::reftpl(r())); 00582 } 00583 00584 }; 00585 00586 } /* namespace ivl */ 00587 00588 #endif // IVL_CORE_DETAILS_IVL_FUNC_IVL_FUNC_HPP 00589