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_KEYWORD_OPERATORS_RET_HPP 00025 #define IVL_CORE_DETAILS_KEYWORD_OPERATORS_RET_HPP 00026 00027 namespace ivl { 00028 00029 template< 00030 class T1, class T2 = types::skip, 00031 class T3 = types::skip, class T4 = types::skip, 00032 class T5 = types::skip, class T6 = types::skip, 00033 class T7 = types::skip, class T8 = types::skip, 00034 class T9 = types::skip, class T10 = types::skip > 00035 class ret; 00036 00037 template <class T> 00038 class ret<T, types::skip, 00039 types::skip, types::skip, 00040 types::skip, types::skip, 00041 types::skip, types::skip, 00042 types::skip, types::skip> : 00043 public //ivl::scalar<T>//TODO:t_if 00044 types::t_if<types::is_builtin<T>, ivl::scalar<T>, T>::type 00045 { 00046 typedef typename types::t_if<types::is_builtin<T>, ivl::scalar<T>, T> 00047 ::type prv_base_class; 00048 public: 00049 typedef prv_base_class ret_base_class; 00050 T& ret_base() { return static_cast<T&>(*this); } 00051 const T& ret_base() const { return static_cast<const T&>(*this); } 00052 00053 ret() { } 00054 ret(const ret& x) : prv_base_class(static_cast<const T&>(x)) { } 00055 // other array constructors, just pass any template arguments, up to four. 00056 template<class A1> 00057 ret(const A1& a1) : prv_base_class(a1) { } 00058 template<class A1, class A2> 00059 ret(const A1& a1, const A2& a2) : prv_base_class(a1, a2) { } 00060 template<class A1, class A2, class A3> 00061 ret(const A1& a1, const A2& a2, const A3& a3) 00062 : prv_base_class(a1, a2, a3) { } 00063 template<class A1, class A2, class A3, class A4> 00064 ret(const A1& a1, const A2& a2, const A3& a3, const A4& a4) 00065 : prv_base_class(a1, a2, a3, a4) { } 00066 00067 ret& operator=(const ret& x) 00068 { 00069 // do not propagate copy constructor normally 00070 // as this would ruin the case ret = ret which 00071 // has to be swapped, so we need ret_base() = ret. 00072 prv_base_class::operator=(x); 00073 return *this; 00074 } 00075 template<class K> 00076 ret& operator=(const K& x) 00077 { 00078 prv_base_class::operator=(x); 00079 return *this; 00080 } 00081 }; 00082 00083 namespace core_details { 00084 00085 template <class T, class NOT_BARE> 00086 struct ret_t_op 00087 { 00088 typedef typename types::t_if<types::is_ivl_array<T>, ret<T>, T>::type type; 00089 }; 00090 00091 template <class T> 00092 struct ret_t_op<T, types::t_true> 00093 { 00094 typedef T type; 00095 }; 00096 00097 template <class T> 00098 struct ret_t : public ret_t_op<T, 00099 typename types::t_or<types::is_ref<T>, types::is_ptr<T> >::type> { }; 00100 00101 } /* namespace core_details */ 00102 00103 template< 00104 class T1, class T2, 00105 class T3, class T4, 00106 class T5, class T6, 00107 class T7, class T8, 00108 class T9, class T10> 00109 class ret 00110 : public 00111 ivl::internal::tuple< 00112 typename core_details::ret_t<T1>::type, typename core_details::ret_t<T2>::type, 00113 typename core_details::ret_t<T3>::type, typename core_details::ret_t<T4>::type, 00114 typename core_details::ret_t<T5>::type, typename core_details::ret_t<T6>::type, 00115 typename core_details::ret_t<T7>::type, typename core_details::ret_t<T8>::type, 00116 typename core_details::ret_t<T9>::type, typename core_details::ret_t<T10>::type> 00117 { 00118 typedef ivl::internal::tuple< 00119 typename core_details::ret_t<T1>::type, typename core_details::ret_t<T2>::type, 00120 typename core_details::ret_t<T3>::type, typename core_details::ret_t<T4>::type, 00121 typename core_details::ret_t<T5>::type, typename core_details::ret_t<T6>::type, 00122 typename core_details::ret_t<T7>::type, typename core_details::ret_t<T8>::type, 00123 typename core_details::ret_t<T9>::type, typename core_details::ret_t<T10>::type> 00124 tpl; 00125 public: 00126 ret() {} 00127 ret(const ret& a) : tpl(a) { } 00128 template<class F> 00129 ret(const F& f) : tpl(f) { } 00130 }; 00131 00132 } /* namespace ivl */ 00133 00134 #endif // IVL_CORE_DETAILS_KEYWORD_OPERATORS_RET_HPP