Mirror reflection library - Rubber type-erasure utility 0.5.13

rubber/rubber.hpp

Go to the documentation of this file.
00001 
00010 #ifndef RUBBER_RUBBER_1103151301_HPP
00011 #define RUBBER_RUBBER_1103151301_HPP
00012 
00013 #include <rubber/config.hpp>
00014 #include <rubber/wrap.hpp>
00015 #include <rubber/range.hpp>
00016 #include <rubber/specifiers.hpp>
00017 #include <rubber/meta_objects.hpp>
00018 #include <puddle/auxiliary/fwd.hpp>
00019 
00020 #include <functional>
00021 
00040 
00041 
00044 RUBBER_NAMESPACE_BEGIN
00045 
00046 template <class MirrorMetaObject>
00047 auto erase_type(void) ->
00048 decltype(wrap<MirrorMetaObject>())
00049 {
00050     return wrap<MirrorMetaObject>();
00051 }
00052 
00053 template <class MirrorMetaObject>
00054 auto erase_type(const puddle::aux::meta_type<MirrorMetaObject>& mo) ->
00055 decltype(wrap<MirrorMetaObject>())
00056 {
00057     return wrap<MirrorMetaObject>();
00058 }
00059 
00060 namespace aux {
00061 
00062 template <typename ... Wrappers>
00063 class eraser_base;
00064 
00065 template <>
00066 class eraser_base<>
00067 {
00068 public:
00069     template <typename MetaObject>
00070     void call(const MetaObject& mo) const
00071     { }
00072 };
00073 
00074 template <typename Wrapper, typename ... Wrappers>
00075 class eraser_base<Wrapper, Wrappers ...>
00076 {
00077 private:
00078     typedef std::function<void(const Wrapper&)> functor_type;
00079     functor_type functor;
00080     eraser_base<Wrappers...> base;
00081 
00082     template <typename MetaObject>
00083     void do_call(const MetaObject& mo, std::false_type) const
00084     {
00085         base.call(mo);
00086     }
00087 
00088     template <typename MetaObject>
00089     void do_call(const MetaObject& mo, std::true_type) const
00090     {
00091         functor(wrap_into<Wrapper>(mo));
00092     }
00093 public:
00094     eraser_base(
00095         const functor_type& func,
00096         const std::function<void(const Wrappers&)>& ... fns
00097     ): functor(func)
00098      , base(fns ...)
00099     { }
00100 
00101     template <typename MetaObject>
00102     void call(const MetaObject& mo) const
00103     {
00104         typename mirror::mp::is_a<
00105             MetaObject,
00106             typename tag_by_wrapper<Wrapper>::type
00107         >::type selector;
00108         do_call(mo, selector);
00109     }
00110 };
00111 
00112 } // namespace aux
00113 
00114 template <typename ... Wrappers>
00115 class eraser
00116 {
00117 private:
00118     aux::eraser_base<Wrappers...> base;
00119 public:
00120     eraser(const std::function<void(const Wrappers&)>& ... fns)
00121      : base(fns...)
00122     { }
00123 
00124     template <typename MetaObject>
00125     void operator()(MetaObject mo) const
00126     {
00127         base.call(mo);
00128     }
00129 };
00130 
00131 RUBBER_NAMESPACE_END
00132 
00133 #endif //include guard
00134 

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.