File indexing completed on 2025-01-18 09:38:19
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_ICL_DETAIL_ELEMENT_ITERATOR_HPP_JOFA_091104
0009 #define BOOST_ICL_DETAIL_ELEMENT_ITERATOR_HPP_JOFA_091104
0010
0011 #include <boost/mpl/if.hpp>
0012 #include <boost/iterator/iterator_facade.hpp>
0013 #include <boost/icl/type_traits/succ_pred.hpp>
0014 #include <boost/icl/detail/mapped_reference.hpp>
0015
0016 namespace boost{namespace icl
0017 {
0018
0019
0020 template<class Type>
0021 struct is_std_pair
0022 {
0023 typedef is_std_pair<Type> type;
0024 BOOST_STATIC_CONSTANT(bool, value = false);
0025 };
0026
0027 template<class FirstT, class SecondT>
0028 struct is_std_pair<std::pair<FirstT, SecondT> >
0029 {
0030 typedef is_std_pair<std::pair<FirstT, SecondT> > type;
0031 BOOST_STATIC_CONSTANT(bool, value = true);
0032 };
0033
0034
0035
0036 template<class Type>
0037 struct first_element
0038 {
0039 typedef Type type;
0040 };
0041
0042 template<class FirstT, class SecondT>
0043 struct first_element<std::pair<FirstT, SecondT> >
0044 {
0045 typedef FirstT type;
0046 };
0047
0048
0049 template <class SegmentIteratorT> class element_iterator;
0050
0051 template<class IteratorT>
0052 struct is_reverse
0053 {
0054 typedef is_reverse type;
0055 BOOST_STATIC_CONSTANT(bool, value = false);
0056 };
0057
0058 template<class BaseIteratorT>
0059 struct is_reverse<std::reverse_iterator<BaseIteratorT> >
0060 {
0061 typedef is_reverse<std::reverse_iterator<BaseIteratorT> > type;
0062 BOOST_STATIC_CONSTANT(bool, value = true);
0063 };
0064
0065 template<class BaseIteratorT>
0066 struct is_reverse<icl::element_iterator<BaseIteratorT> >
0067 {
0068 typedef is_reverse<icl::element_iterator<BaseIteratorT> > type;
0069 BOOST_STATIC_CONSTANT(bool, value = is_reverse<BaseIteratorT>::value);
0070 };
0071
0072
0073 template<class SegmentT>
0074 struct elemental;
0075
0076 #ifdef ICL_USE_INTERVAL_TEMPLATE_TEMPLATE
0077
0078 template<class DomainT, ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE) Interval>
0079 struct elemental<ICL_INTERVAL_TYPE(Interval,DomainT,Compare) >
0080 {
0081 typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) segment_type;
0082 typedef segment_type interval_type;
0083 typedef DomainT type;
0084 typedef DomainT domain_type;
0085 typedef DomainT codomain_type;
0086 typedef DomainT transit_type;
0087 };
0088
0089 template< class DomainT, class CodomainT,
0090 ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE) Interval >
0091 struct elemental<std::pair<ICL_INTERVAL_TYPE(Interval,DomainT,Compare) const, CodomainT> >
0092 {
0093 typedef std::pair<ICL_INTERVAL_TYPE(Interval,DomainT,Compare), CodomainT> segment_type;
0094 typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) interval_type;
0095 typedef std::pair<DomainT, CodomainT> type;
0096 typedef DomainT domain_type;
0097 typedef CodomainT codomain_type;
0098 typedef mapped_reference<DomainT, CodomainT> transit_type;
0099 };
0100
0101 #else
0102
0103 template<ICL_INTERVAL(ICL_COMPARE) Interval>
0104 struct elemental
0105 {
0106 typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) segment_type;
0107 typedef segment_type interval_type;
0108 typedef typename interval_traits<interval_type>::domain_type domain_type;
0109 typedef domain_type type;
0110 typedef domain_type codomain_type;
0111 typedef domain_type transit_type;
0112 };
0113
0114 template< class CodomainT, ICL_INTERVAL(ICL_COMPARE) Interval >
0115 struct elemental<std::pair<ICL_INTERVAL_TYPE(Interval,DomainT,Compare) const, CodomainT> >
0116 {
0117 typedef std::pair<ICL_INTERVAL_TYPE(Interval,DomainT,Compare), CodomainT> segment_type;
0118 typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) interval_type;
0119 typedef typename interval_traits<interval_type>::domain_type domain_type;
0120 typedef CodomainT codomain_type;
0121 typedef std::pair<domain_type, codomain_type> type;
0122 typedef mapped_reference<domain_type, codomain_type> transit_type;
0123 };
0124
0125 #endif
0126
0127
0128
0129
0130
0131 template<class SegmentIteratorT, class SegmentT>
0132 struct segment_adapter;
0133
0134 #ifdef ICL_USE_INTERVAL_TEMPLATE_TEMPLATE
0135
0136 template<class SegmentIteratorT, class DomainT, ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE) Interval>
0137 struct segment_adapter<SegmentIteratorT, ICL_INTERVAL_TYPE(Interval,DomainT,Compare) >
0138 {
0139 typedef segment_adapter type;
0140 typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) segment_type;
0141 typedef segment_type interval_type;
0142 typedef typename interval_type::difference_type domain_difference_type;
0143 typedef DomainT domain_type;
0144 typedef DomainT codomain_type;
0145 typedef domain_type element_type;
0146 typedef domain_type& transit_type;
0147
0148 static domain_type first (const SegmentIteratorT& leaper){ return leaper->first(); }
0149 static domain_type last (const SegmentIteratorT& leaper){ return leaper->last(); }
0150 static domain_difference_type length(const SegmentIteratorT& leaper){ return leaper->length();}
0151
0152 static transit_type transient_element(domain_type& inter_pos, const SegmentIteratorT& leaper,
0153 const domain_difference_type& sneaker)
0154 {
0155 inter_pos = is_reverse<SegmentIteratorT>::value ? leaper->last() - sneaker
0156 : leaper->first() + sneaker;
0157 return inter_pos;
0158 }
0159 };
0160
0161 template < class SegmentIteratorT, class DomainT, class CodomainT,
0162 ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE) Interval >
0163 struct segment_adapter<SegmentIteratorT, std::pair<ICL_INTERVAL_TYPE(Interval,DomainT,Compare) const, CodomainT> >
0164 {
0165 typedef segment_adapter type;
0166 typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) interval_type;
0167 typedef DomainT domain_type;
0168 typedef std::pair<DomainT, CodomainT> element_type;
0169 typedef CodomainT codomain_type;
0170 typedef mapped_reference<DomainT, CodomainT> transit_type;
0171 typedef typename difference_type_of<interval_traits<interval_type> >::type
0172 domain_difference_type;
0173
0174 static domain_type first (const SegmentIteratorT& leaper){ return leaper->first.first(); }
0175 static domain_type last (const SegmentIteratorT& leaper){ return leaper->first.last(); }
0176 static domain_difference_type length(const SegmentIteratorT& leaper){ return leaper->first.length();}
0177
0178 static transit_type transient_element(domain_type& inter_pos, const SegmentIteratorT& leaper,
0179 const domain_difference_type& sneaker)
0180 {
0181 inter_pos = is_reverse<SegmentIteratorT>::value ? leaper->first.last() - sneaker
0182 : leaper->first.first() + sneaker;
0183 return transit_type(inter_pos, leaper->second);
0184 }
0185 };
0186
0187 #else
0188
0189 template<class SegmentIteratorT, ICL_INTERVAL(ICL_COMPARE) Interval>
0190 struct segment_adapter
0191 {
0192 typedef segment_adapter type;
0193 typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) segment_type;
0194 typedef segment_type interval_type;
0195 typedef typename interval_traits<interval_type>::domain_type domain_type;
0196 typedef domain_type codomain_type;
0197 typedef domain_type element_type;
0198 typedef domain_type& transit_type;
0199 typedef typename difference_type_of<interval_traits<interval_type> >::type
0200 domain_difference_type;
0201
0202 static domain_type first (const SegmentIteratorT& leaper){ return leaper->first(); }
0203 static domain_type last (const SegmentIteratorT& leaper){ return leaper->last(); }
0204 static domain_difference_type length(const SegmentIteratorT& leaper){ return icl::length(*leaper);}
0205
0206 static transit_type transient_element(domain_type& inter_pos, const SegmentIteratorT& leaper,
0207 const domain_difference_type& sneaker)
0208 {
0209 inter_pos = is_reverse<SegmentIteratorT>::value ? icl::last(*leaper) - sneaker
0210 : icl::first(*leaper) + sneaker;
0211 return inter_pos;
0212 }
0213 };
0214
0215 template < class SegmentIteratorT, class CodomainT, ICL_INTERVAL(ICL_COMPARE) Interval >
0216 struct segment_adapter<SegmentIteratorT, std::pair<ICL_INTERVAL_TYPE(Interval,DomainT,Compare) const, CodomainT> >
0217 {
0218 typedef segment_adapter type;
0219 typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) interval_type;
0220 typedef typename interval_traits<interval_type>::domain_type domain_type;
0221 typedef CodomainT codomain_type;
0222 typedef std::pair<domain_type, codomain_type> element_type;
0223 typedef mapped_reference<domain_type, CodomainT> transit_type;
0224 typedef typename difference_type_of<interval_traits<interval_type> >::type
0225 domain_difference_type;
0226
0227 static domain_type first (const SegmentIteratorT& leaper){ return leaper->first.first(); }
0228 static domain_type last (const SegmentIteratorT& leaper){ return leaper->first.last(); }
0229 static domain_difference_type length(const SegmentIteratorT& leaper){ return icl::length(leaper->first);}
0230
0231 static transit_type transient_element(domain_type& inter_pos, const SegmentIteratorT& leaper,
0232 const domain_difference_type& sneaker)
0233 {
0234 inter_pos = is_reverse<SegmentIteratorT>::value ? icl::last(leaper->first) - sneaker
0235 : icl::first(leaper->first) + sneaker;
0236 return transit_type(inter_pos, leaper->second);
0237 }
0238 };
0239
0240 #endif
0241
0242 template <class SegmentIteratorT>
0243 class element_iterator
0244 : public boost::iterator_facade<
0245 element_iterator<SegmentIteratorT>
0246 , typename elemental<typename SegmentIteratorT::value_type>::transit_type
0247 , boost::bidirectional_traversal_tag
0248 , typename elemental<typename SegmentIteratorT::value_type>::transit_type
0249 >
0250 {
0251 public:
0252 typedef element_iterator type;
0253 typedef SegmentIteratorT segment_iterator;
0254 typedef typename SegmentIteratorT::value_type segment_type;
0255 typedef typename first_element<segment_type>::type interval_type;
0256 typedef typename elemental<segment_type>::type element_type;
0257 typedef typename elemental<segment_type>::domain_type domain_type;
0258 typedef typename elemental<segment_type>::codomain_type codomain_type;
0259 typedef typename elemental<segment_type>::transit_type transit_type;
0260 typedef transit_type value_type;
0261 typedef typename difference_type_of<interval_traits<interval_type> >::type
0262 domain_difference_type;
0263
0264 private:
0265 typedef typename segment_adapter<segment_iterator,segment_type>::type adapt;
0266
0267 struct enabler{};
0268
0269 public:
0270 element_iterator()
0271 : _saltator(identity_element<segment_iterator>::value())
0272 , _reptator(identity_element<domain_difference_type>::value()){}
0273
0274 explicit element_iterator(segment_iterator jumper)
0275 : _saltator(jumper), _reptator(identity_element<domain_difference_type>::value()) {}
0276
0277 template <class SaltatorT>
0278 element_iterator
0279 ( element_iterator<SaltatorT> const& other
0280 , typename enable_if<boost::is_convertible<SaltatorT*,SegmentIteratorT*>, enabler>::type = enabler())
0281 : _saltator(other._saltator), _reptator(other._reptator) {}
0282
0283 private:
0284 friend class boost::iterator_core_access;
0285 template <class> friend class element_iterator;
0286
0287 template <class SaltatorT>
0288 bool equal(element_iterator<SaltatorT> const& other) const
0289 {
0290 return this->_saltator == other._saltator
0291 && this->_reptator == other._reptator;
0292 }
0293
0294 void increment()
0295 {
0296 if(_reptator < icl::pred(adapt::length(_saltator)))
0297 ++_reptator;
0298 else
0299 {
0300 ++_saltator;
0301 _reptator = identity_element<domain_difference_type>::value();
0302 }
0303 }
0304
0305 void decrement()
0306 {
0307 if(identity_element<domain_difference_type>::value() < _reptator)
0308 --_reptator;
0309 else
0310 {
0311 --_saltator;
0312 _reptator = adapt::length(_saltator);
0313 --_reptator;
0314 }
0315 }
0316
0317 value_type dereference()const
0318 {
0319 return adapt::transient_element(_inter_pos, _saltator, _reptator);
0320 }
0321
0322 private:
0323 segment_iterator _saltator;
0324 mutable domain_difference_type _reptator;
0325 mutable domain_type _inter_pos;
0326
0327 };
0328
0329 }}
0330
0331 #endif
0332
0333
0334