Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
access-casted-o.hpp
Go to the documentation of this file.
1/*
2 ACCESS-CASTED.hpp - util template to access a value using conversion or cast as appropriate
3
4 Copyright (C)
5 2008, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12*/
13
14
36#ifndef UTIL_ACCESS_CASTED_O_H
37#define UTIL_ACCESS_CASTED_O_H
38
39#include <type_traits>
40
41
42
43namespace util {
44
45 namespace {
46 using std::remove_pointer;
47 using std::remove_reference;
48 using std::is_convertible;
49 using std::is_polymorphic;
50 using std::is_base_of;
51
52
53 template <typename SRC, typename TAR>
54 struct can_cast : std::false_type {};
55
56 template <typename SRC, typename TAR>
57 struct can_cast<SRC*,TAR*> { enum { value = is_base_of<SRC,TAR>::value };};
58
59 template <typename SRC, typename TAR>
60 struct can_cast<SRC*&,TAR*> { enum { value = is_base_of<SRC,TAR>::value };};
61
62 template <typename SRC, typename TAR>
63 struct can_cast<SRC&,TAR&> { enum { value = is_base_of<SRC,TAR>::value };};
64
65
66 template <typename T>
67 struct hasRTTI
68 {
69 typedef typename remove_pointer<
70 typename remove_reference<T>::type>::type TPlain;
71
72 enum { value = is_polymorphic<TPlain>::value };
73 };
74
75 template <typename SRC, typename TAR>
83
84 template <typename SRC, typename TAR>
86 {
87 enum { value = can_cast<SRC,TAR>::value
90 )
91 };
92 };
93
94 template <typename SRC, typename TAR>
96 {
97 enum { value = is_convertible<SRC,TAR>::value
100 )
101 };
102 };
103
104
105
106 template<typename X>
107 struct EmptyVal
108 {
109 static X create() { return X(); }
110 };
111 template<typename X>
112 struct EmptyVal<X*&>
113 {
114 static X*& create() { static X* nullP(0); return nullP; }
115 };
116
117 }
118
119
120
121
122 template<typename RET>
124 {
125 typedef RET Ret;
126
127 static RET access (...) { return ifEmpty(); }
128 static RET ifEmpty () { return EmptyVal<RET>::create(); }
129 };
130
131 template<typename TAR>
133 {
134 using NullAccessor<TAR>::access;
135
136 template<typename ELM>
137 static typename std::enable_if< use_dynamic_downcast<ELM&,TAR>::value,
138 TAR >::type
139 access (ELM& elem)
140 {
141 return dynamic_cast<TAR> (elem);
142 }
143
144 template<typename ELM>
145 static typename std::enable_if< use_static_downcast<ELM&,TAR>::value,
146 TAR >::type
147 access (ELM& elem)
148 {
149 return static_cast<TAR> (elem);
150 }
151
152 template<typename ELM>
153 static typename std::enable_if< use_conversion<ELM&,TAR>::value,
154 TAR >::type
155 access (ELM& elem)
156 {
157 return elem;
158 }
159 };
160
161
162} // namespace util
163#endif
static std::enable_if< use_dynamic_downcast< ELM &, TAR >::value, TAR >::type access(ELM &elem)
static std::enable_if< use_conversion< ELM &, TAR >::value, TAR >::type access(ELM &elem)
static std::enable_if< use_static_downcast< ELM &, TAR >::value, TAR >::type access(ELM &elem)
static RET access(...)
remove_pointer< typenameremove_reference< T >::type >::type TPlain