Mirror reflection library - Lagoon run-time layer 0.5.13

lagoon/range/chain.hpp

Go to the documentation of this file.
00001 
00010 #ifndef LAGOON_RANGE_CHAIN_1011291729_HPP
00011 #define LAGOON_RANGE_CHAIN_1011291729_HPP
00012 
00013 #include <lagoon/range/utils.hpp>
00014 #include <cassert>
00015 
00016 LAGOON_NAMESPACE_BEGIN
00017 
00018 namespace aux {
00019 
00020 // Helper class containing one of the chained ranges
00021 template <size_t Index, class Range>
00022 struct chained_unit
00023 {
00024     Range range;
00025 
00026     chained_unit(const Range& rng)
00027      : range(rng)
00028     { }
00029 };
00030 
00031 // Tree composing the individual units of a chained range
00032 template <size_t RootIndex, class ValueType, class ... Ranges>
00033 struct chained_unit_tree;
00034 
00035 // Leaf of a chain unit tree
00036 template <size_t RootIndex, class ValueType, class Range>
00037 struct chained_unit_tree<RootIndex, ValueType, Range>
00038  : chained_unit<RootIndex, Range>
00039 {
00040     enum {unit_count = RootIndex + 1};
00041     typedef chained_unit<RootIndex, Range> leaf;
00042 
00043     chained_unit_tree(const Range& rng)
00044      : leaf(rng)
00045     { }
00046 
00047     bool empty(size_t current) const
00048     {
00049         assert(current >= RootIndex);
00050         return leaf::range.empty();
00051     }
00052 
00053     void skip_empty(size_t& current)
00054     {
00055         assert(current >= RootIndex);
00056         // since this is the last one
00057         // we don't have to skip anything here
00058     }
00059 
00060     void step_front(size_t& current)
00061     {
00062         assert(current == RootIndex);
00063         leaf::range.step_front();
00064         if(leaf::range.empty()) ++current;
00065     }
00066 
00067     ValueType front(size_t current) const
00068     {
00069         assert(current == RootIndex);
00070         return leaf::range.front();
00071     }
00072 };
00073 
00074 // The implementation of the chained unit tree
00075 template <size_t RootIndex, class ValueType, class Range, class ... Ranges>
00076 struct chained_unit_tree<RootIndex, ValueType, Range, Ranges...>
00077  : chained_unit<RootIndex, Range>
00078  , chained_unit_tree<RootIndex + 1, ValueType, Ranges...>
00079 {
00080     typedef chained_unit<RootIndex, Range> leaf;
00081     typedef chained_unit_tree<RootIndex + 1, ValueType, Ranges...> tree;
00082 
00083     chained_unit_tree(
00084         const Range& rng,
00085         const Ranges&... rngs
00086     ): leaf(rng)
00087      , tree(rngs...)
00088     { }
00089 
00090     bool empty(size_t current) const
00091     {
00092         if(current == RootIndex) return leaf::range.empty();
00093         else return tree::empty(current);
00094     }
00095 
00096     void skip_empty(size_t& current)
00097     {
00098         assert(current == RootIndex);
00099         if(leaf::range.empty())
00100         {
00101             ++current;
00102             tree::skip_empty(current);
00103         }
00104     }
00105 
00106     void step_front(size_t& current)
00107     {
00108         if(current == RootIndex)
00109         {
00110             leaf::range.step_front();
00111             if(leaf::range.empty())
00112             {
00113                 ++current;
00114                 tree::skip_empty(current);
00115             }
00116         }
00117         else tree::step_front(current);
00118     }
00119 
00120     ValueType front(size_t current) const
00121     {
00122         if(current == RootIndex)
00123             return leaf::range.front();
00124         else return tree::front(current);
00125     }
00126 };
00127 
00128 template <typename ValueType, class ... Ranges>
00129 class chained
00130  : private chained_unit_tree<0, ValueType, Ranges...>
00131  , public leaping_base
00132 {
00133 private:
00134     typedef chained_unit_tree<0, ValueType, Ranges...>
00135         base_class;
00136 
00137     // The current range unit to be used
00138     size_t current;
00139 public:
00141     chained(const Ranges&...rngs)
00142      : base_class(rngs...)
00143      , current(0)
00144     {
00145         base_class::skip_empty(current);
00146     }
00147 
00149     bool empty(void) const
00150     {
00151         return base_class::empty(current);
00152     }
00153 
00155     void step_front(void)
00156     {
00157         assert(!empty());
00158         base_class::step_front(current);
00159     }
00160 
00161     size_t leap_front(size_t leap)
00162     {
00163         return leaping_base::do_leap_front(*this, leap);
00164     }
00165 
00167     ValueType front(void) const
00168     {
00169         assert(!empty());
00170         return base_class::front(current);
00171     }
00172 };
00173 
00174 } // namespace aux
00175 
00176 #ifdef MIRROR_DOCUMENTATION_ONLY
00177 
00178 
00190 template <typename ValueType, class ... Ranges>
00191 UnspecifiedRange<ValueType> chain(const Ranges&...ranges);
00192 
00194 
00205 template <typename Interface, class ... Ranges>
00206 UnspecifiedRange<shared<Interface> > chain_mo(const Ranges&...ranges);
00207 #else
00208 
00209 // chain with arbitrary value type
00210 template <typename ValueType, class ... Ranges>
00211 aux::chained<ValueType, Ranges...> chain(const Ranges&...ranges)
00212 {
00213     return aux::chained<ValueType, Ranges...>(ranges...);
00214 }
00215 
00216 // chain of shared meta-object ranges
00217 template <typename Interface, class ... Ranges>
00218 aux::chained<shared<Interface>, Ranges...> chain_mo(const Ranges&...ranges)
00219 {
00220     return aux::chained<shared<Interface>, Ranges...>(ranges...);
00221 }
00222 #endif
00223 
00224 LAGOON_NAMESPACE_END
00225 
00226 #endif //include guard
00227 

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.