28 #ifndef REMORA_DETAIL_ITERATOR_HPP 29 #define REMORA_DETAIL_ITERATOR_HPP 32 #include <type_traits> 37 #include "../detail/check.hpp" 39 namespace remora{
namespace iterators{
46 struct sparse_bidirectional_iterator_tag:
public std::bidirectional_iterator_tag{};
47 struct packed_random_access_iterator_tag:
public std::random_access_iterator_tag{};
48 struct dense_random_access_iterator_tag:
public packed_random_access_iterator_tag{};
58 template<
class I,
class T>
59 struct bidirectional_iterator_base:
60 public std::iterator<sparse_bidirectional_iterator_tag, T> {
61 typedef I derived_iterator_type;
62 typedef T derived_value_type;
65 derived_iterator_type operator ++ (
int) {
66 derived_iterator_type &d(*static_cast<const derived_iterator_type *>(
this));
67 derived_iterator_type tmp(d);
72 derived_iterator_type operator -- (
int) {
73 derived_iterator_type &d(*static_cast<const derived_iterator_type *>(
this));
74 derived_iterator_type tmp(d);
81 bool operator != (
const derived_iterator_type &it)
const {
82 const derived_iterator_type *d =
static_cast<const derived_iterator_type *
>(
this);
98 template<
class I,
class T,
class Tag>
99 struct random_access_iterator_base
100 :
public std::iterator<Tag, T> {
101 typedef I derived_iterator_type;
102 typedef T derived_value_type;
103 typedef std::ptrdiff_t difference_type;
113 friend I operator + (random_access_iterator_base
const& it, difference_type n) {
114 I tmp(static_cast<const I&>(it));
117 friend I operator - (random_access_iterator_base
const& it, difference_type n) {
118 I tmp(static_cast<const I&>(it));
122 friend I operator + (difference_type n, random_access_iterator_base
const& it) {
123 I tmp(static_cast<const I&>(it));
126 friend I operator - (difference_type n, random_access_iterator_base
const& it) {
127 I tmp(static_cast<const I&>(it));
132 template<
class I,
class T,
class Tag>
133 I operator ++ (random_access_iterator_base<I,T,Tag>& it,
int) {
134 I& d =
static_cast<I&
>(it);
140 template<
class I,
class T,
class Tag>
141 I operator -- (random_access_iterator_base<I,T,Tag>& it,
int) {
142 I& d =
static_cast<I&
>(it);
150 template<
class I1,
class T1,
class I2,
class T2,
class Tag>
152 random_access_iterator_base<I1,T1,Tag>
const& it1,
153 random_access_iterator_base<I2,T2,Tag>
const& it2
155 I1
const& d1 =
static_cast<const I1&
>(it1);
156 I2
const& d2 =
static_cast<const I2&
>(it2);
160 template<
class I1,
class T1,
class I2,
class T2,
class Tag>
162 random_access_iterator_base<I1,T1,Tag>
const& it1,
163 random_access_iterator_base<I2,T2,Tag>
const& it2
165 I1
const& d1 =
static_cast<const I1&
>(it1);
166 I2
const& d2 =
static_cast<const I2&
>(it2);
170 template<
class I1,
class T1,
class I2,
class T2,
class Tag>
172 random_access_iterator_base<I1,T1,Tag>
const& it1,
173 random_access_iterator_base<I2,T2,Tag>
const& it2
175 I1
const& d1 =
static_cast<const I1&
>(it1);
176 I2
const& d2 =
static_cast<const I2&
>(it2);
180 template<
class I1,
class T1,
class I2,
class T2,
class Tag>
182 random_access_iterator_base<I1,T1,Tag>
const& it1,
183 random_access_iterator_base<I2,T2,Tag>
const& it2
185 I1
const& d1 =
static_cast<const I1&
>(it1);
186 I2
const& d2 =
static_cast<const I2&
>(it2);
193 struct iterator_base_traits {};
196 struct iterator_base_traits<sparse_bidirectional_iterator_tag> {
197 template<
class I,
class T>
198 struct iterator_base {
199 typedef bidirectional_iterator_base<I, T> type;
203 struct iterator_base_traits<dense_random_access_iterator_tag> {
204 template<
class I,
class T>
205 struct iterator_base {
206 typedef random_access_iterator_base<I, T, dense_random_access_iterator_tag> type;
211 struct iterator_base_traits<packed_random_access_iterator_tag> {
212 template<
class I,
class T>
213 struct iterator_base {
214 typedef random_access_iterator_base<I, T, packed_random_access_iterator_tag> type;
218 template<
class Closure>
219 class indexed_iterator:
220 public random_access_iterator_base<
221 indexed_iterator<Closure>,
222 typename Closure::value_type,
223 dense_random_access_iterator_tag
226 typedef std::size_t size_type;
227 typedef std::ptrdiff_t difference_type;
228 typedef typename Closure::value_type value_type;
229 typedef typename std::conditional<
230 std::is_const<Closure>::value,
231 typename Closure::const_reference,
232 typename Closure::reference
237 indexed_iterator(Closure container, size_type index)
238 : m_index(index), m_closure(container) {}
241 indexed_iterator(indexed_iterator<C>
const& iterator)
242 : m_index(iterator.m_index), m_closure(iterator.m_closure) {}
245 indexed_iterator& operator++() {
249 indexed_iterator& operator--() {
253 indexed_iterator& operator += (difference_type n) {
257 indexed_iterator& operator -= (difference_type n) {
262 difference_type operator - (indexed_iterator<T>
const& it)
const {
263 return m_index - it.m_index;
267 reference operator *()
const {
268 REMORA_RANGE_CHECK(m_index < m_closure.size());
269 return m_closure(m_index);
271 reference operator [](difference_type n)
const {
272 REMORA_RANGE_CHECK(m_index+n < m_closure.size());
273 return m_closure(m_index+n);
277 size_type index()
const {
283 indexed_iterator &operator = (indexed_iterator<T>
const& it) {
284 m_closure = it.m_closure;
285 m_index = it.m_index;
291 bool operator == (indexed_iterator<T>
const& it)
const {
292 return m_index == it.m_index;
295 bool operator < (indexed_iterator<T>
const& it)
const {
296 return m_index < it.m_index;
302 template<
class>
friend class indexed_iterator;
305 template<
class T,
class Tag=dense_random_access_iterator_tag>
306 class dense_storage_iterator:
307 public random_access_iterator_base<
308 dense_storage_iterator<T,Tag>,
309 typename std::remove_const<T>::type,
313 typedef std::size_t size_type;
314 typedef std::ptrdiff_t difference_type;
315 typedef typename std::remove_const<T>::type value_type;
316 typedef T& reference;
320 dense_storage_iterator():m_pos(0),m_index(0) {}
321 dense_storage_iterator(pointer pos, size_type index, difference_type stride = 1)
322 :m_pos(pos), m_index(index), m_stride(stride) {}
325 dense_storage_iterator(dense_storage_iterator<U,Tag>
const& iter)
326 :m_pos(iter.m_pos), m_index(iter.m_index), m_stride(iter.m_stride){}
329 dense_storage_iterator& operator=(dense_storage_iterator<U,Tag>
const& iter){
331 m_index = iter.m_index;
332 m_stride = iter.m_stride;
337 dense_storage_iterator& operator ++ () {
342 dense_storage_iterator& operator -- () {
347 dense_storage_iterator& operator += (difference_type n) {
352 dense_storage_iterator& operator -= (difference_type n) {
358 difference_type operator - (dense_storage_iterator<U,Tag>
const& it)
const {
360 return (difference_type)m_index - (difference_type)it.m_index;
364 reference operator*()
const {
367 reference operator [](difference_type n)
const {
368 return m_pos[m_stride*n];
372 size_type index()
const {
378 bool operator == (dense_storage_iterator<U,Tag>
const& it)
const {
381 return m_index == it.m_index;
384 bool operator < (dense_storage_iterator<U,Tag>
const& it)
const {
386 return m_index < it.m_index;
392 difference_type m_stride;
393 template<
class,
class>
friend class dense_storage_iterator;
395 template<
class T,
class I>
396 class compressed_storage_iterator:
397 public bidirectional_iterator_base<
398 compressed_storage_iterator<T,I>,typename std::remove_const<T>::type
401 typedef typename std::remove_const<T>::type value_type;
402 typedef typename std::remove_const<I>::type size_type;
403 typedef std::ptrdiff_t difference_type;
404 typedef T& reference;
408 compressed_storage_iterator() {}
409 compressed_storage_iterator(
410 T* value_array, I* index_array,
411 size_type position, size_type row = 0
413 : m_values(value_array),m_indices(index_array)
414 , m_position(position), m_row(row){}
416 template<
class U,
class V>
417 compressed_storage_iterator(compressed_storage_iterator<U,V>
const& it) {
418 m_position = it.m_position;
420 m_values = it.m_values;
421 m_indices = it.m_indices;
424 template<
class U,
class V>
425 compressed_storage_iterator &operator = (compressed_storage_iterator<U,V>
const& it) {
426 m_position = it.m_position;
428 m_values = it.m_values;
429 m_indices = it.m_indices;
434 compressed_storage_iterator &operator++ () {
438 compressed_storage_iterator &operator -- () {
439 REMORA_RANGE_CHECK(m_position > 0);
445 reference operator* ()
const {
446 return m_values[m_position];
448 size_type index()
const {
449 return m_indices[m_position];
452 template<
class U,
class V>
453 difference_type operator - (compressed_storage_iterator<U,V>
const& it)
const {
454 REMORA_RANGE_CHECK(m_values == it.m_values);
455 REMORA_RANGE_CHECK(m_indices == it.m_indices);
456 return difference_type(m_position) - difference_type(it.m_position);
459 size_type row()
const{
463 template<
class U,
class V>
464 bool operator == (compressed_storage_iterator<U,V>
const &it)
const {
465 REMORA_RANGE_CHECK(m_values == it.m_values);
466 REMORA_RANGE_CHECK(m_indices == it.m_indices);
467 return m_position == it.m_position;
473 std::size_t m_position;
475 template<
class,
class>
friend class compressed_storage_iterator;
478 template<
class BaseIterator>
479 class subrange_iterator:
480 public iterator_base_traits<typename BaseIterator::iterator_category>::template
481 iterator_base<subrange_iterator<BaseIterator>, typename BaseIterator::value_type>::type {
483 template<
class Iterator>
484 Iterator incrementToIndex(
485 Iterator iter, Iterator end, std::size_t index, dense_random_access_iterator_tag
487 REMORA_SIZE_CHECK(iter.index()<= index);
488 return iter+(index-iter.index());
490 template<
class Iterator>
491 Iterator incrementToIndex(
492 Iterator iter, Iterator end, std::size_t index, packed_random_access_iterator_tag
495 REMORA_RANGE_CHECK(iter.index() < index);
496 return iter+std::min<std::ptrdiff_t>(std::ptrdiff_t(index-iter.index()),end-iter);
501 template<
class Iterator>
502 Iterator incrementToIndex(
503 Iterator iter, Iterator end, std::size_t index,sparse_bidirectional_iterator_tag
505 while (iter != end && iter.index() < index)++iter;
508 template<
class Iterator>
509 Iterator incrementToIndex(
510 Iterator iter, Iterator end, std::size_t index
512 return incrementToIndex(iter,end,index,
typename Iterator::iterator_category());
515 typedef typename BaseIterator::value_type value_type;
516 typedef typename BaseIterator::difference_type difference_type;
517 typedef typename BaseIterator::reference reference;
518 typedef typename BaseIterator::pointer pointer;
521 subrange_iterator() {}
523 subrange_iterator(BaseIterator
const &it, BaseIterator
const &end, std::size_t startIterIndex,std::size_t startIndex)
524 : m_iterator(incrementToIndex(it,end,startIterIndex)),m_start(startIndex) {}
526 subrange_iterator(BaseIterator
const &it, std::size_t startIndex)
527 : m_iterator(it),m_start(startIndex) {}
529 template<
class Iterator>
530 subrange_iterator(subrange_iterator<Iterator>
const &it)
531 :m_iterator(it.m_iterator), m_start(it.m_start) {}
534 subrange_iterator &operator ++ () {
539 subrange_iterator &operator -- () {
544 subrange_iterator &operator += (difference_type n) {
549 subrange_iterator &operator -= (difference_type n) {
554 difference_type operator - (subrange_iterator
const &it)
const {
555 return m_iterator - it.m_iterator;
559 reference operator * ()
const {
562 reference operator [](difference_type n)
const {
567 std::size_t index()
const {
568 return m_iterator.index() - m_start;
572 template<
class Iterator>
573 subrange_iterator &operator = (subrange_iterator<Iterator>
const &it) {
574 m_iterator = it.m_iterator;
575 m_start = it.m_start;
580 template<
class Iterator>
581 bool operator == (subrange_iterator<Iterator>
const &it)
const {
582 return m_iterator == it.m_iterator;
584 template<
class Iterator>
585 bool operator < (subrange_iterator<Iterator>
const &it)
const {
586 return m_iterator < it.m_iterator;
589 BaseIterator inner()
const {
594 BaseIterator m_iterator;
596 template<
class>
friend class subrange_iterator;
601 class constant_iterator:
602 public random_access_iterator_base<
603 constant_iterator<T>,
604 typename std::remove_const<T>::type,
605 dense_random_access_iterator_tag
608 typedef std::size_t size_type;
609 typedef std::ptrdiff_t difference_type;
610 typedef T value_type;
611 typedef value_type
const &reference;
612 typedef value_type
const *pointer;
615 constant_iterator() {}
616 constant_iterator(value_type value, size_type position)
617 :m_position(position),m_value(value) {}
620 constant_iterator &operator ++ () {
624 constant_iterator &operator -- () {
628 constant_iterator &operator += (difference_type n) {
632 constant_iterator &operator -= (difference_type n) {
636 difference_type operator - (constant_iterator
const &it)
const {
637 return m_position - it.m_position;
641 reference operator * ()
const {
644 reference operator [](difference_type n)
const {
649 size_type index()
const {
655 constant_iterator &operator = (constant_iterator
const &it) {
656 m_position = it.m_position;
657 m_value = it.m_value;
662 bool operator == (constant_iterator
const &it)
const {
663 return m_position == it.m_position;
665 bool operator < (constant_iterator
const &it)
const {
666 return m_position < it.m_position;
669 size_type m_position;
673 template<
class BaseIterator,
class F>
674 class transform_iterator:
675 public iterator_base_traits<typename BaseIterator::iterator_category>::template
676 iterator_base<transform_iterator<BaseIterator,F>, typename BaseIterator::value_type>::type {
678 typedef typename BaseIterator::iterator_category iterator_category;
679 typedef std::size_t size_type;
680 typedef std::ptrdiff_t difference_type;
681 typedef typename std::result_of<F(typename BaseIterator::value_type)>::type value_type;
682 typedef value_type reference;
683 typedef value_type *pointer;
686 transform_iterator() {}
687 transform_iterator(BaseIterator
const &it,F functor)
688 :m_position(it),m_functor(functor) {}
691 transform_iterator &operator ++ () {
695 transform_iterator &operator -- () {
699 transform_iterator &operator += (difference_type n) {
703 transform_iterator &operator -= (difference_type n) {
707 difference_type operator - (transform_iterator
const &it)
const {
708 return m_position - it.m_position;
712 reference operator * ()
const {
713 return m_functor(*m_position);
715 reference operator [](difference_type n)
const {
720 size_type index()
const {
721 return m_position.index();
726 transform_iterator &operator = (transform_iterator<Iter,F>
const &it) {
727 m_position = it.m_position;
728 m_functor = it.m_functor;
733 bool operator == (transform_iterator
const &it)
const {
734 return m_position == it.m_position;
736 bool operator < (transform_iterator
const &it)
const {
737 return m_position < it.m_position;
741 BaseIterator m_position;
746 class one_hot_iterator:
public bidirectional_iterator_base<one_hot_iterator<T>, T> {
748 typedef T value_type;
749 typedef std::ptrdiff_t difference_type;
750 typedef std::size_t size_type;
751 typedef T& reference;
752 typedef T
const& const_reference;
753 typedef value_type
const* pointer;
757 one_hot_iterator(size_type index, value_type value,
bool isEnd)
758 :m_index(index),m_value(value),m_isEnd(isEnd){}
761 one_hot_iterator& operator ++ () {
765 one_hot_iterator& operator -- () {
771 reference operator*()
const {
776 size_type index()
const{
781 one_hot_iterator& operator = (one_hot_iterator
const& it) {
782 m_index = it.m_index;
783 m_value = it.m_value;
788 bool operator == (one_hot_iterator
const& it)
const {
789 REMORA_RANGE_CHECK(m_index == it.m_index);
790 return m_isEnd == it.m_isEnd;
800 template<
class I1,
class I2>
801 struct iterator_restrict_traits {
802 typedef I1 iterator_category;
806 struct iterator_restrict_traits<dense_random_access_iterator_tag, sparse_bidirectional_iterator_tag> {
807 typedef sparse_bidirectional_iterator_tag iterator_category;
811 struct iterator_restrict_traits<packed_random_access_iterator_tag,dense_random_access_iterator_tag> {
812 typedef dense_random_access_iterator_tag iterator_category;
816 struct iterator_restrict_traits<packed_random_access_iterator_tag,sparse_bidirectional_iterator_tag> {
817 typedef sparse_bidirectional_iterator_tag iterator_category;
820 template<
class Iterator1,
class Iterator2,
class F>
821 class binary_transform_iterator:
822 public iterator_base_traits<
823 typename iterator_restrict_traits<
824 typename Iterator1::iterator_category,
825 typename Iterator2::iterator_category
827 >::template iterator_base<
828 binary_transform_iterator<Iterator1,Iterator2,F>,
829 typename std::result_of<F(typename Iterator1::value_type, typename Iterator2::value_type)>::type
832 typedef typename Iterator1::iterator_category category1;
833 typedef typename Iterator2::iterator_category category2;
835 typedef typename iterator_restrict_traits<
838 >::iterator_category iterator_category;
839 typedef std::size_t size_type;
840 typedef std::ptrdiff_t difference_type;
841 typedef typename std::result_of<F(typename Iterator1::value_type, typename Iterator2::value_type)>::type value_type;
842 typedef value_type reference;
843 typedef value_type *pointer;
846 binary_transform_iterator() {}
847 binary_transform_iterator(
849 Iterator1
const &it1, Iterator1
const &end1,
850 Iterator2
const &it2, Iterator2
const &end2
852 , m_iterator1(it1), m_end1(end1)
853 , m_iterator2(it2), m_end2(end2)
857 ensureValidPosition(category1(),category2());
860 if(m_iterator1 != end1 && m_iterator2 != end2)
861 m_index = std::min(m_iterator1.index(),m_iterator2.index());
870 void ensureValidPosition(
871 dense_random_access_iterator_tag,
872 dense_random_access_iterator_tag
875 dense_random_access_iterator_tag,
876 dense_random_access_iterator_tag
883 dense_random_access_iterator_tag,
884 dense_random_access_iterator_tag
891 dense_random_access_iterator_tag,
892 dense_random_access_iterator_tag,
899 value_type dereference(
900 dense_random_access_iterator_tag,
901 dense_random_access_iterator_tag
903 return m_functor(*m_iterator1, *m_iterator2);
907 void ensureValidPosition(
908 sparse_bidirectional_iterator_tag,
909 sparse_bidirectional_iterator_tag
912 if(F::left_zero_remains || F::right_zero_remains){
914 m_iterator1 != m_end1 && m_iterator2 != m_end2
915 && m_iterator1.index() != m_iterator2.index()
917 if(m_iterator1.index() < m_iterator2.index())
922 if( m_iterator1 == m_end1 || m_iterator2 == m_end2){
923 m_iterator2 = m_end2;
924 m_iterator1 = m_end1;
929 sparse_bidirectional_iterator_tag,
930 sparse_bidirectional_iterator_tag
932 if(F::left_zero_remains || F::right_zero_remains){
935 ensureValidPosition(category1(),category2());
937 if (m_iterator1 != m_end1 && m_iterator2 != m_end2){
938 if( m_iterator1.index() == m_iterator2.index()){
942 else if(m_iterator1.index() < m_iterator2.index())
946 }
else if(m_iterator1 != m_end1){
952 size_type index1 = std::numeric_limits<size_type>::max();
953 size_type index2 = std::numeric_limits<size_type>::max();
954 if(m_iterator1 != m_end1)
955 index1 = m_iterator1.index();
956 if(m_iterator2 != m_end2)
957 index2 = m_iterator2.index();
959 m_index = std::min(index1, index2);
962 sparse_bidirectional_iterator_tag,
963 sparse_bidirectional_iterator_tag
965 if (m_index <= m_iterator1.index())
967 if (m_index <= m_iterator2.index())
969 m_index = std::max(m_iterator1.index(), m_iterator2.index());
972 sparse_bidirectional_iterator_tag,
973 sparse_bidirectional_iterator_tag,
977 increment(category1(),category2());
981 decrement(category1(),category2());
985 value_type dereference(
986 sparse_bidirectional_iterator_tag,
987 sparse_bidirectional_iterator_tag
989 value_type t1 = value_type();
990 if (m_iterator1 != m_end1 && m_iterator1.index() == m_index)
992 value_type t2 = value_type();
993 if (m_iterator2 != m_end2 && m_iterator2.index() == m_index)
995 return m_functor(t1, t2);
1000 void ensureValidPosition(
1001 dense_random_access_iterator_tag,
1002 sparse_bidirectional_iterator_tag
1004 if(F::right_zero_remains){
1005 m_iterator1 += m_iterator2.index()-m_iterator1.index();
1010 dense_random_access_iterator_tag,
1011 sparse_bidirectional_iterator_tag
1013 if(F::right_zero_remains){
1015 m_iterator1 += m_iterator2.index()-m_iterator1.index();
1017 if (m_iterator2 != m_end2){
1018 if( m_iterator1.index() == m_iterator2.index()){
1022 else if(m_iterator2.index() > m_iterator1.index())
1029 size_type index1 = m_iterator1.index();
1030 size_type index2 = std::numeric_limits<size_type>::max();
1031 if(m_iterator2 != m_end2)
1032 index2 = m_iterator2.index();
1033 m_index = std::min(index1, index2);
1036 dense_random_access_iterator_tag,
1037 sparse_bidirectional_iterator_tag
1039 if(F::right_zero_remains){
1041 m_iterator1 -= m_iterator1.index()-m_iterator2.index();
1043 if (m_index <= m_iterator1.index())
1045 if (m_index <= m_iterator2.index())
1047 m_index = std::max(m_iterator1.index(), m_iterator2.index());
1051 dense_random_access_iterator_tag,
1052 sparse_bidirectional_iterator_tag,
1056 increment(category1(),category2());
1060 decrement(category1(),category2());
1064 value_type dereference(
1065 dense_random_access_iterator_tag,
1066 sparse_bidirectional_iterator_tag
1068 typedef typename Iterator2::value_type value_type2;
1069 value_type t2 = value_type2();
1070 if (m_iterator2 != m_end2 && m_iterator2.index() == m_index)
1072 return m_functor(*m_iterator1, t2);
1076 void ensureValidPosition(
1077 sparse_bidirectional_iterator_tag,
1078 dense_random_access_iterator_tag
1080 if(F::left_zero_remains){
1081 m_iterator2 += m_iterator1.index()-m_iterator2.index();
1085 sparse_bidirectional_iterator_tag,
1086 dense_random_access_iterator_tag
1088 if(F::left_zero_remains){
1090 m_iterator2 += m_iterator1.index()-m_iterator2.index();
1092 if (m_iterator1 != m_end1){
1093 if( m_iterator1.index() == m_iterator2.index()){
1097 else if(m_iterator1.index() > m_iterator2.index())
1104 size_type index1 = std::numeric_limits<size_type>::max();
1105 size_type index2 = m_iterator2.index();
1106 if(m_iterator1 != m_end1)
1107 index1 = m_iterator1.index();
1108 m_index = std::min(index1, index2);
1111 sparse_bidirectional_iterator_tag,
1112 dense_random_access_iterator_tag
1114 if(F::left_zero_remains){
1116 m_iterator2 -= m_iterator2.index()-m_iterator1.index();
1118 if (m_index <= m_iterator2.index())
1120 if (m_index <= m_iterator1.index())
1122 m_index = std::max(m_iterator1.index(), m_iterator2.index());
1126 sparse_bidirectional_iterator_tag,
1127 dense_random_access_iterator_tag,
1131 increment(category1(),category2());
1135 decrement(category1(),category2());
1139 value_type dereference(
1140 sparse_bidirectional_iterator_tag,
1141 dense_random_access_iterator_tag
1143 typedef typename Iterator1::value_type value_type1;
1144 value_type t1 = value_type1();
1145 if (m_iterator1 != m_end1 && m_iterator1.index() == m_index)
1147 return m_functor(t1,*m_iterator2);
1152 binary_transform_iterator &operator ++ () {
1153 increment(category1(),category2());
1156 binary_transform_iterator &operator -- () {
1157 decrement(category1(),category2());
1160 binary_transform_iterator &operator += (difference_type n) {
1161 increment(category1(),category2(), n);
1164 binary_transform_iterator &operator -= (difference_type n) {
1165 increment(category1(),category2(), -n);
1168 difference_type operator - (
const binary_transform_iterator &it)
const {
1169 difference_type diff1 = m_iterator1- it.m_iterator1;
1170 difference_type diff2 = m_iterator2- it.m_iterator2;
1171 return std::abs(diff1) > std::abs(diff2)? diff1:diff2;
1175 reference operator * ()
const {
1176 return dereference(category1(),category2());
1178 reference operator [](difference_type n)
const {
1179 return *(*
this + n);
1183 size_type index()
const {
1188 binary_transform_iterator &operator = (binary_transform_iterator
const &it) {
1189 m_index = it.m_index;
1190 m_iterator1 = it.m_iterator1;
1192 m_iterator2 = it.m_iterator2;
1198 bool operator == (binary_transform_iterator
const &it)
const {
1199 return m_iterator1 == it.m_iterator1 && m_iterator2 == it.m_iterator2;
1201 bool operator < (binary_transform_iterator
const &it)
const {
1202 return m_iterator1 < it.m_iterator1 || m_iterator2 < it.m_iterator2;
1206 Iterator1 m_iterator1;
1208 Iterator2 m_iterator2;