ivl 679
ivl/details/core/tool/pointer_face.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_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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations