Mirror reflection library - Lagoon run-time layer 0.5.13
|
00001 00011 #ifndef LAGOON_UTILS_1011291729_HPP 00012 #define LAGOON_UTILS_1011291729_HPP 00013 00014 #include <lagoon/lagoon_fwd.hpp> 00015 #include <lagoon/range/fwd_decl.hpp> 00016 #include <vector> 00017 #include <cassert> 00018 00019 LAGOON_NAMESPACE_BEGIN 00020 00027 template <typename MetaObject> class shared; 00028 00029 namespace aux { 00030 00031 // helper function used for getting to the wrapped raw pointer inside 00032 // of a shared<MetaObject> in internal code 00033 // NOTE: this is an implementation detail, never use this function in 00034 // client code 00035 template <typename MetaObject> 00036 MetaObject* _get_mo(const shared<MetaObject>&); 00037 00038 } // namespace aux 00039 00041 00048 template <typename MetaObject> 00049 class shared 00050 { 00051 private: 00052 MetaObject* mo; 00053 00054 MetaObject* get(void) const 00055 { 00056 return mo; 00057 } 00058 00059 friend MetaObject* aux::_get_mo<>(const shared<MetaObject>&); 00060 public: 00061 inline shared(void) 00062 : mo(nullptr) 00063 { } 00064 00065 explicit inline shared(MetaObject* p) 00066 : mo(p) 00067 { } 00068 00069 template <class OtherMO> 00070 inline shared(const shared<OtherMO>& other) 00071 : mo(aux::_get_mo(other)) 00072 { } 00073 00074 inline operator bool (void) const 00075 { 00076 return mo != nullptr; 00077 } 00078 00079 inline bool operator ! (void) const 00080 { 00081 return mo == nullptr; 00082 } 00083 00084 inline MetaObject* operator -> (void) const 00085 { 00086 assert(mo != nullptr); 00087 return mo; 00088 } 00089 00091 00098 template <class Interface> 00099 shared<Interface> as(void) const 00100 { 00101 // try to cast to the specified interface 00102 #if MIRROR_NO_RTTI 00103 Interface* imo = static_cast<Interface*>(get()->cast_to( 00104 categorize_interface((Interface*)nullptr) 00105 )); 00106 #else 00107 Interface* imo = dynamic_cast<Interface*>(get()); 00108 #endif 00109 // wrap the raw pointer and return it 00110 return shared<Interface>(imo); 00111 } 00112 00114 00117 template <class Interface> 00118 bool is(void) const 00119 { 00120 return mo->self()->is_a(categorize_interface( 00121 (Interface*)nullptr 00122 )); 00123 } 00124 }; 00125 00126 namespace aux { 00127 00128 template <typename MetaObject> 00129 inline MetaObject* _get_mo(const shared<MetaObject>& shared_mo) 00130 { 00131 return shared_mo.get(); 00132 } 00133 00134 } // namespace aux 00135 00136 00138 00143 template <class SharedMetaObject> 00144 struct shared_meta_object; 00145 00146 // Implementation of the shared_meta_object trait 00147 template <class MetaObject> 00148 struct shared_meta_object<shared<MetaObject> > 00149 { 00150 typedef MetaObject type; 00151 }; 00152 00153 template <typename MetaObject> 00154 class range; 00155 00157 00162 template <typename MetaObject, class Iterator> 00163 class range_base 00164 { 00165 protected: 00166 typedef Iterator iterator; 00167 iterator current, end; 00168 friend class lagoon::aux::std_range_adapt<range<MetaObject> >; 00169 public: 00171 00174 inline range_base(const iterator& b, const iterator& e) 00175 : current(b) 00176 , end(e) 00177 { } 00178 00180 inline bool empty(void) const 00181 { 00182 return end == current; 00183 } 00184 00186 inline size_t size(void) const 00187 { 00188 return end - current; 00189 } 00190 00192 void step_front(void) 00193 { 00194 assert(!empty()); 00195 ++current; 00196 } 00197 00199 00204 size_t leap_front(size_t leap) 00205 { 00206 if(leap > size()) 00207 { 00208 current = end; 00209 return size(); 00210 } 00211 else 00212 { 00213 current += leap; 00214 return leap; 00215 } 00216 } 00217 00219 const shared<MetaObject>& front(void) const 00220 { 00221 assert(!empty()); 00222 return *current; 00223 } 00224 00226 shared<MetaObject> at(size_t offs) const 00227 { 00228 assert(offs < size()); 00229 return *(current + offs); 00230 } 00231 00233 friend bool same_position(const range_base& a, const range_base& b) 00234 { 00235 return a.current == b.current; 00236 } 00237 }; 00238 00240 00246 template <typename MetaObject> 00247 class range : public range_base< 00248 MetaObject, 00249 typename std::vector<shared<MetaObject> >::const_iterator 00250 > 00251 { 00252 private: 00253 typedef range_base< 00254 MetaObject, 00255 typename std::vector<shared<MetaObject> >::const_iterator 00256 > base_class; 00257 typedef typename base_class::iterator iterator; 00258 friend class lagoon::aux::std_range_adapt<range<MetaObject> >; 00259 public: 00260 // TODO: replace this when inherited constructors become supported 00261 inline range(const iterator& b, const iterator& e) 00262 : base_class(b, e) 00263 { } 00264 }; 00265 00266 #ifdef MIRROR_DOCUMENTATION_ONLY 00267 00268 00273 template <typename Range> 00274 struct range_meta_object 00275 { 00276 typedef unspecified type; 00277 }; 00278 #else 00279 template <typename Range> 00280 struct range_meta_object 00281 { 00282 private: 00283 static Range& dummy_range(void); 00284 public: 00285 typedef typename shared_meta_object< 00286 decltype(dummy_range().front()) 00287 >::type type; 00288 }; 00289 #endif 00290 00291 template <typename MetaObject> 00292 struct range_meta_object<range<MetaObject> > 00293 { 00294 typedef MetaObject type; 00295 }; 00296 00297 LAGOON_NAMESPACE_END 00298 00299 #endif //include guard 00300