Mirror reflection library 0.5.13

mirror/meta_container.hpp

Go to the documentation of this file.
00001 
00011 #ifndef MIRROR_META_CONTAINER_1104181551_HPP
00012 #define MIRROR_META_CONTAINER_1104181551_HPP
00013 
00014 #include <mirror/mirror_fwd.hpp>
00015 #include <mirror/meta_object_tags.hpp>
00016 #include <mirror/cntnr_kind_tags.hpp>
00017 #include <mirror/cntnr_op_param_tags.hpp>
00018 #include <mirror/preprocessor.hpp>
00019 #include <mirror/auxiliary/scoped_named.hpp>
00020 #include <mirror/auxiliary/containers.hpp>
00021 #include <string>
00022 #include <type_traits>
00023 
00024 MIRROR_NAMESPACE_BEGIN
00025 
00026 namespace _container {
00027 
00028 template <typename Container>
00029 struct _
00030 {
00031     typedef std::integral_constant<int, 0> cntnr_count;
00032     typedef non_container_tag kind;
00033 };
00034 
00035 template <size_t Size>
00036 struct _array_base
00037 {
00038     static bool empty(const void*)
00039     {
00040         return Size == 0;
00041     }
00042 
00043     static size_t size_hint(const void*)
00044     {
00045         return Size;
00046     }
00047 
00048     typedef mirror::mp::empty_range inserters;
00049     typedef mirror::mp::empty_range erasers;
00050 };
00051 
00052 template <class ElementType, size_t Size>
00053 struct _<ElementType[Size]>
00054 {
00055     struct cntnr : _array_base<Size>
00056     {
00057         typedef ElementType elem_type;
00058 
00059         typedef mirror::aux::meta_array_trav_fwd<
00060             ElementType,
00061             Size
00062         > default_traversal;
00063 
00064         typedef mirror::mp::range<
00065             default_traversal
00066             // TODO: reverse traversal ?
00067         > traversals;
00068 
00069         typedef mirror::mp::range<
00070             // TODO: begin/end/at/... ?
00071         > locators;
00072     };
00073     static cntnr _cntnr(std::integral_constant<int, 0>);
00074     typedef std::integral_constant<int, 1> cntnr_count;
00075     typedef simple_container_tag kind;
00076 };
00077 
00078 } // namespace _container
00079 
00080 template <class Container, typename IsSpecial, int Index>
00081 struct meta_container
00082 {
00083 private:
00084     typedef decltype(
00085         mirror::_container::_<Container>::_cntnr(
00086             std::integral_constant<int, Index>()
00087         )
00088     ) _base_cntnr;
00089 
00090     friend class default_traversal<meta_container>;
00091     friend class traversals<meta_container>;
00092     friend class locators<meta_container>;
00093     friend class inserters<meta_container>;
00094     friend class erasers<meta_container>;
00095 
00096     // gets the scope for regular (class) containers
00097     static typename mirror::reflected<Container>::type
00098     _get_scope(std::false_type);
00099 
00100     // scope for special container types (like arrays)
00101     static typename mirror::reflected<Container>::type::scope
00102     _get_scope(std::true_type);
00103 public:
00104     typedef typename mirror::reflected<
00105         typename _base_cntnr::elem_type
00106     >::type element_type;
00107 
00108     typedef decltype(_get_scope(IsSpecial())) scope;
00109 
00110     static bool empty(const Container& container)
00111     {
00112         return _base_cntnr::empty(container);
00113     }
00114 
00115     static auto size_hint(const Container& container) ->
00116     decltype(_base_cntnr::size_hint(container))
00117     {
00118         return _base_cntnr::size_hint(container);
00119     }
00120 
00121     typedef typename _base_cntnr::default_traversal
00122         default_traversal;
00123 };
00124 
00125 template <class Container>
00126 struct container_kind<meta_type<Container> >
00127 {
00128     typedef typename mirror::_container::_<
00129         Container
00130     >::kind type;
00131 };
00132 
00133 template <class Container>
00134 struct container_kind<meta_class<Container> >
00135  : public container_kind<meta_type<Container> >
00136 { };
00137 
00138 template <class Container>
00139 struct container_kind<meta_enum<Container> >
00140  : public container_kind<meta_type<Container> >
00141 { };
00142 
00143 template <class Container>
00144 struct containers<meta_type<Container> >
00145 {
00146     typedef typename mirror::mp::apply_on_seq_pack<
00147         mirror::aux::cntnr_helper<Container>,
00148         typename mirror::_container::_<Container>::cntnr_count
00149     >::type type;
00150 };
00151 
00152 template <class Container>
00153 struct containers<meta_class<Container> >
00154  : public containers<meta_type<Container> >
00155 { };
00156 
00157 template <class Container>
00158 struct containers<meta_enum<Container> >
00159 {
00160     typedef mirror::mp::empty_range type;
00161 };
00162 
00163 template <class Container>
00164 struct all_containers<meta_class<Container> >
00165 {
00166     // TODO: inherited containers
00167     typedef typename mirror::mp::apply_on_seq_pack<
00168         mirror::aux::cntnr_helper<Container>,
00169         typename mirror::_container::_<Container>::cntnr_count
00170     >::type type;
00171 };
00172 
00173 template <class Container, class IsSpecial, int Index>
00174 struct default_traversal<meta_container<Container, IsSpecial, Index> >
00175 {
00176     typedef typename meta_container<
00177         Container,
00178         IsSpecial,
00179         Index
00180     >::_base_cntnr::default_traversal type;
00181 };
00182 
00183 template <class Container, class IsSpecial, int Index>
00184 struct traversals<meta_container<Container, IsSpecial, Index> >
00185 {
00186     typedef typename meta_container<
00187         Container,
00188         IsSpecial,
00189         Index
00190     >::_base_cntnr::traversals type;
00191 };
00192 
00193 template <class Container, class IsSpecial, int Index>
00194 struct locators<meta_container<Container, IsSpecial, Index> >
00195 {
00196     typedef typename meta_container<
00197         Container,
00198         IsSpecial,
00199         Index
00200     >::_base_cntnr::locators type;
00201 };
00202 
00203 template <class Container, class IsSpecial, int Index>
00204 struct inserters<meta_container<Container, IsSpecial, Index> >
00205 {
00206     typedef typename meta_container<
00207         Container,
00208         IsSpecial,
00209         Index
00210     >::_base_cntnr::inserters type;
00211 };
00212 
00213 template <class Container, class IsSpecial, int Index>
00214 struct erasers<meta_container<Container, IsSpecial, Index> >
00215 {
00216     typedef typename meta_container<
00217         Container,
00218         IsSpecial,
00219         Index
00220     >::_base_cntnr::erasers type;
00221 };
00222 
00223 // utilities
00224 
00226 
00234 struct element_traversal_info
00235 {
00236 #ifndef MIRROR_DOCUMNETATION_ONLY
00237     // Implementation details use the member functions instead
00238     int _elem_done;
00239     int _cntnr_idx;
00240     int _elem_idx;
00241     bool _first_cntnr;
00242     bool _last_cntnr;
00243     bool _first_elem;
00244     bool _last_elem;
00245 #endif
00246 
00247 
00252     const int elements_done(void) const
00253     {
00254         return _elem_done;
00255     }
00256 
00258 
00263     const int container_index(void) const
00264     {
00265         return _cntnr_idx;
00266     }
00267 
00269     const bool first_container(void) const
00270     {
00271         return _first_cntnr;
00272     }
00273 
00275     const bool last_container(void) const
00276     {
00277         return _last_cntnr;
00278     }
00279 
00281     const int element_position(void) const
00282     {
00283         return _elem_idx;
00284     }
00285 
00287     const bool first_in_container(void) const
00288     {
00289         return _first_elem;
00290     }
00291 
00293     const bool last_in_container(void) const
00294     {
00295         return _last_elem;
00296     }
00297 };
00298 
00299 namespace aux {
00300 
00301 template <
00302     typename Kind,
00303     typename Container,
00304     typename ElemFunctor,
00305     typename EmptyFunctor
00306 >
00307 struct trav_elems_hlpr
00308 {
00309     Kind& kind_tag;
00310     int& done;
00311     int& cntnr_idx;
00312     Container& cntnr;
00313     ElemFunctor& elem_func;
00314     EmptyFunctor& empty_func;
00315 
00316     template <typename IterInfo>
00317     void operator()(IterInfo) const
00318     {
00319         typedef typename IterInfo::type meta_cntnr;
00320         if(meta_cntnr::empty(cntnr))
00321         {
00322             element_traversal_info info = {
00323                 done,
00324                 cntnr_idx,
00325                 -1,
00326                 bool(IterInfo::is_first::value),
00327                 bool(IterInfo::is_last::value),
00328                 false,
00329                 false
00330             };
00331             empty_func(kind_tag, info);
00332         }
00333         else
00334         {
00335             auto tr = meta_cntnr::
00336                 default_traversal::
00337                 start(cntnr);
00338             int elem_idx = 0;
00339             while(!tr.done())
00340             {
00341                 auto loc = tr.front();
00342                 tr.step_front();
00343                 element_traversal_info info = {
00344                     done,
00345                     cntnr_idx,
00346                     elem_idx,
00347                     bool(IterInfo::is_first::value),
00348                     bool(IterInfo::is_last::value),
00349                     bool(elem_idx == 0),
00350                     bool(tr.done())
00351                 };
00352                 elem_func(kind_tag, info, loc.get());
00353                 ++elem_idx;
00354                 ++done;
00355             }
00356         }
00357         ++cntnr_idx;
00358     }
00359 };
00360 
00361 template <
00362     template <class> class Getter,
00363     class MetaType,
00364     typename Container,
00365     typename ElemFunctor,
00366     typename EmptyFunctor
00367 > int do_trav_elems(
00368     MetaType,
00369     Container& inst,
00370     ElemFunctor elem_func,
00371     EmptyFunctor empty_func
00372 )
00373 {
00374     int done = 0, cntnr_idx = 0;
00375     typedef typename mirror::container_kind<
00376         MetaType
00377     >::type Kind;
00378     Kind kind;
00379     trav_elems_hlpr<
00380         Kind,
00381         Container,
00382         ElemFunctor,
00383         EmptyFunctor
00384     > hlpr = {
00385         kind,
00386         done,
00387         cntnr_idx,
00388         inst,
00389         elem_func,
00390         empty_func
00391     };
00392     mirror::mp::for_each_ii<
00393         typename Getter<MetaType>::type
00394     >(hlpr);
00395     return done;
00396 }
00397 
00398 } // namespace aux
00399 
00400 template <typename Container, typename ElemFunctor, typename EmptyFunctor>
00401 int traverse_elements(
00402     meta_type<Container> mt,
00403     Container& inst,
00404     ElemFunctor elem_func,
00405     EmptyFunctor empty_func
00406 )
00407 {
00408     return mirror::aux::do_trav_elems<
00409         mirror::containers
00410     >(mt, inst, elem_func, empty_func);
00411 }
00412 
00413 template <typename Container, typename ElemFunctor, typename EmptyFunctor>
00414 int traverse_elements(
00415     meta_class<Container> mc,
00416     Container& inst,
00417     ElemFunctor elem_func,
00418     EmptyFunctor empty_func
00419 )
00420 {
00421     return mirror::aux::do_trav_elems<
00422         mirror::all_containers
00423     >(mc, inst, elem_func, empty_func);
00424 }
00425 
00426 MIRROR_NAMESPACE_END
00427 
00428 #endif //include guard
00429 

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.