Mirror reflection library - Lagoon run-time layer 0.5.13

lagoon/utils.hpp

Go to the documentation of this file.
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 

Copyright © 2006-2011 Matus Chochlik, University of Zilina, Zilina, Slovakia.
<matus.chochlik -at- fri.uniza.sk>
<chochlik -at -gmail.com>
Documentation generated on Fri Dec 16 2011 by Doxygen (version 1.7.3).
Important note: Although the 'boostified' version of Mirror uses the Boost C++ libraries Coding Guidelines and is implemented inside of the boost namespace, it IS NOT an officially reviewed and accepted Boost library. Mirror is being developed with the intention to be submitted for review for inclusion to the Boost C++ libraries.