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_TOOL_POINTER_FACE_HPP 00025 #define IVL_CORE_DETAILS_TOOL_POINTER_FACE_HPP 00026 00027 /* 00028 * The class pointer_face<T> immitates the behavior of a pointer but 00029 * implements an actual copy of a value of type T. It can be also described 00030 * as the opposite thing to the C++ reference. 00031 * The usability is important when we are specializing with templates and 00032 * we want to have pointer to a structure in some cases and value in some 00033 * other cases, but we write a single implementation that only solves the 00034 * pointer case, and we "mask" the values into pointers with this simple wrapper. 00035 */ 00036 00037 namespace ivl { 00038 namespace internal { 00039 00040 template <class T> 00041 struct pointer_face 00042 { 00043 T val; 00044 00045 // constructors 00046 pointer_face() { } 00047 pointer_face(const T* ptr) : val(*ptr) { } 00048 pointer_face(const T& val) : val(val) { } 00049 pointer_face(const pointer_face& o) : val(o.val) { } 00050 00051 // operator ='s 00052 pointer_face& operator=(const T* ptr) { this->val = *ptr; return *this; } 00053 pointer_face& operator=(const T& val) { this->val = val; return *this; } 00054 pointer_face& operator=(const pointer_face& o) 00055 { this->val = o.val; return *this; } 00056 00057 // dereference 00058 T& operator *() { return val; } 00059 const T& operator *() const { return val; } 00060 T* operator ->() { return &val; } 00061 const T* operator ->() const { return &val; } 00062 }; 00063 00064 template <class T> 00065 struct pointer_face<const T> 00066 { 00067 T val; 00068 00069 // constructors 00070 pointer_face() { } 00071 pointer_face(const T* ptr) : val(*ptr) { } 00072 pointer_face(const T& val) : val(val) { } 00073 pointer_face(const pointer_face& o) : val(o.val) { } 00074 00075 // operator ='s 00076 pointer_face& operator=(const T* ptr) { this->val = *ptr; return *this; } 00077 pointer_face& operator=(const T& val) { this->val = val; return *this; } 00078 pointer_face& operator=(const pointer_face& o) 00079 { this->val = o.val; return *this; } 00080 00081 // dereference 00082 const T& operator *() const { return val; } 00083 const T* operator ->() const { return &val; } 00084 }; 00085 00086 template <class T> 00087 struct relaxed_pointer_face 00088 { 00089 T val; 00090 00091 // constructors 00092 relaxed_pointer_face() { } 00093 template <class O> 00094 relaxed_pointer_face(const O* ptr) : val(*ptr) { } 00095 template <class O> 00096 relaxed_pointer_face(const O& val) : val(val) { } 00097 relaxed_pointer_face(const relaxed_pointer_face& o) : val(o.val) { } 00098 template <class O> 00099 relaxed_pointer_face(const relaxed_pointer_face<O>& o) 00100 : val(o.val) { } 00101 template <class O> 00102 relaxed_pointer_face(const pointer_face<O>& o) : val(o.val) { } 00103 00104 // operator ='s 00105 template <class O> 00106 relaxed_pointer_face& operator=(const O* ptr) 00107 { this->val = *ptr; return *this; } 00108 template <class O> 00109 relaxed_pointer_face& operator=(const O& val) 00110 { this->val = val; return *this; } 00111 relaxed_pointer_face& operator=(const relaxed_pointer_face& o) 00112 { this->val = o.val; return *this; } 00113 template <class O> 00114 relaxed_pointer_face& operator=(const relaxed_pointer_face<O>& o) 00115 { this->val = o.val; return *this; } 00116 template <class O> 00117 relaxed_pointer_face& operator=(const pointer_face<O>& o) 00118 { this->val = o.val; return *this; } 00119 00120 // dereference 00121 T& operator *() { return val; } 00122 const T& operator *() const { return val; } 00123 T* operator ->() { return &val; } 00124 const T* operator ->() const { return &val; } 00125 }; 00126 00127 template <class T> 00128 struct relinit_pointer_face 00129 { 00130 T val; 00131 00132 // constructors 00133 relinit_pointer_face() { } 00134 template <class O> 00135 relinit_pointer_face(const O* ptr) : val(*ptr) { } 00136 template <class O> 00137 relinit_pointer_face(const O& val) : val(val) { } 00138 relinit_pointer_face(const relinit_pointer_face& o) : val(o.val) { } 00139 template <class O> 00140 relinit_pointer_face(const relinit_pointer_face<O>& o) 00141 : val(o.val) { } 00142 template <class O> 00143 relinit_pointer_face(const pointer_face<O>& o) : val(o.val) { } 00144 00145 // operator ='s 00146 template <class O> 00147 relinit_pointer_face& operator=(const O* ptr) 00148 { this->val.init(*ptr); return *this; } 00149 template <class O> 00150 relinit_pointer_face& operator=(const O& val) 00151 { this->val.init(val); return *this; } 00152 relinit_pointer_face& operator=(const relinit_pointer_face& o) 00153 { this->val.init(o.val); return *this; } 00154 template <class O> 00155 relinit_pointer_face& operator=(const relinit_pointer_face<O>& o) 00156 { this->val.init(o.val); return *this; } 00157 template <class O> 00158 relinit_pointer_face& operator=(const pointer_face<O>& o) 00159 { this->val.init(o.val); return *this; } 00160 00161 // dereference 00162 T& operator *() { return val; } 00163 const T& operator *() const { return val; } 00164 T* operator ->() { return &val; } 00165 const T* operator ->() const { return &val; } 00166 }; 00167 00168 template <class T> 00169 struct builtin_to_class 00170 { 00171 protected: 00172 T v; 00173 public: 00174 builtin_to_class() {} 00175 builtin_to_class(const builtin_to_class& a) : v(a.v) {} 00176 builtin_to_class(const T& v) : v(v) {} 00177 00178 operator T&() { return v; } 00179 operator const T&() const { return v; } 00180 }; 00181 00182 template <class T> 00183 struct builtin_to_class <const T> 00184 { 00185 protected: 00186 T v; 00187 public: 00188 builtin_to_class() {} 00189 builtin_to_class(const builtin_to_class& a) : v(a.v) {} 00190 builtin_to_class(const T& v) : v(v) {} 00191 00192 operator const T&() const { return v; } 00193 //TODO: this is temporary, until proper fix 00194 // or wipe of reference face class 00195 operator ivl::scalar<T>() const { return scalar<T>(v); } 00196 00197 }; 00198 00199 template <class T, class ITER = types::skip> 00200 struct reference_face : public types::t_if< 00201 types::t_or<types::is_builtin<typename types::remove_const<T>::type>, 00202 types::is_ptr<T> >, 00203 builtin_to_class<T>, T>::type 00204 { 00205 private: 00206 typedef typename types::t_if< 00207 types::t_or<types::is_builtin<typename types::remove_const<T>::type>, 00208 types::is_ptr<T> >, builtin_to_class<T>, T>::type builtin_base_class; 00209 ITER& it; 00210 00211 public: 00212 typedef builtin_base_class base_class; 00213 base_class& base() { return static_cast<base_class&>(*this); } 00214 const base_class& base() const 00215 { return static_cast<const base_class&>(*this); } 00216 00217 // constructors 00218 reference_face(const T* ptr, ITER& it) 00219 : builtin_base_class(*ptr), it(it) { } 00220 reference_face(const T& val, ITER& it) 00221 : builtin_base_class(val), it(it) { } 00222 reference_face(const reference_face& o) 00223 : builtin_base_class(static_cast<const T&>(o)), it(o.it) { } 00224 00225 // reference operator 00226 ITER& operator &() { return it; } 00227 const ITER& operator &() const { return it; } 00228 }; 00229 00230 // TODO: When T is pointer we have failure 00231 template <class T, class ITER> 00232 struct reference_face<const T, ITER> : public types::t_if< 00233 types::t_or<types::is_builtin<typename types::remove_const<T>::type>, 00234 types::is_ptr<T> >, builtin_to_class<const T>, T>::type 00235 { 00236 private: 00237 typedef typename types::t_if< 00238 types::t_or<types::is_builtin<typename types::remove_const<T>::type>, 00239 types::is_ptr<T> >, 00240 builtin_to_class<const T>, T>::type builtin_base_class; 00241 const ITER& it; 00242 00243 public: 00244 typedef builtin_base_class base_class; 00245 base_class& base() { return static_cast<base_class&>(*this); } 00246 const base_class& base() const 00247 { return static_cast<const base_class&>(*this); } 00248 00249 // constructors 00250 reference_face(const T* ptr, const ITER& it) 00251 : builtin_base_class(*ptr), it(it) { } 00252 reference_face(const T& val, const ITER& it) 00253 : builtin_base_class(val), it(it) { } 00254 reference_face(const reference_face& o) 00255 : builtin_base_class(static_cast<const T&>(o)), it(o.it) { } 00256 00257 // reference operator 00258 const ITER& operator &() const { return it; } 00259 }; 00260 00261 } /* namespace internal */ 00262 } /* namespace ivl */ 00263 00264 #endif // IVL_CORE_DETAILS_TOOL_POINTER_FACE_HPP