Lumiera  0.pre.03
»edit your freedom«
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 
43 namespace 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>
77  {
78  enum { value = can_cast<SRC,TAR>::value
81  };
82  };
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  {
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