Mirror reflection library 0.5.13
|
00001 00010 #ifndef MIRROR_META_PROG_FLATTEN_1104130956_HPP 00011 #define MIRROR_META_PROG_FLATTEN_1104130956_HPP 00012 00013 #include <mirror/config.hpp> 00014 #include <mirror/meta_prog/range.hpp> 00015 #include <mirror/meta_prog/concat.hpp> 00016 #include <mirror/meta_prog/prepend.hpp> 00017 #include <mirror/meta_prog/can_be_called.hpp> 00018 00019 MIRROR_NAMESPACE_BEGIN 00020 namespace mp { 00021 00022 template <class MetaObject, template <class> class Getter> 00023 struct flatten; 00024 00025 namespace aux { 00026 template <typename Range, template <class> class Getter> 00027 struct fltn_hlpr; 00028 00029 template <typename ... MetaObject, template <class> class Getter> 00030 struct fltn_hlpr<range<MetaObject...>, Getter> 00031 { 00032 typedef typename mirror::mp::concat< 00033 typename mirror::mp::flatten< 00034 MetaObject, 00035 Getter 00036 >::type... 00037 >::type type; 00038 }; 00039 00040 template <typename X, template <class> class Getter, typename Bool> 00041 struct fltn_get; 00042 00043 template <typename X, template <class> class Getter> 00044 struct fltn_get<X, Getter, std::false_type> 00045 { 00046 typedef mirror::mp::empty_range type; 00047 }; 00048 00049 template <typename MetaObject, template <class> class Getter> 00050 struct fltn_get<MetaObject, Getter, std::true_type> 00051 { 00052 typedef typename Getter<MetaObject>::type type; 00053 }; 00054 00055 } // namespace aux 00056 00057 template <class MetaObject, template <class> class Getter> 00058 struct flatten 00059 { 00060 typedef typename prepend< 00061 MetaObject, 00062 typename mirror::mp::aux::fltn_hlpr< 00063 typename mirror::mp::aux::fltn_get< 00064 MetaObject, 00065 Getter, 00066 typename can_be_called<Getter<MetaObject> >::type 00067 >::type, 00068 Getter 00069 >::type 00070 >::type type; 00071 }; 00072 00073 } // namespace mp 00074 MIRROR_NAMESPACE_END 00075 00076 #endif //include guard 00077