@@ -730,7 +730,9 @@ struct common_input_iterator {
730730// * `stride_displacement`, which records the displacement of the calls. This means that both
731731// op++/op+= will increase the displacement counter by 1, and op--/op-= will decrease the
732732// displacement counter by 1.
733- template <class It >
733+ template <class It ,
734+ class StrideCountType = std::iter_difference_t <It>,
735+ class StrideDisplacementType = std::iter_difference_t <It>>
734736class stride_counting_iterator {
735737public:
736738 using value_type = typename iter_value_or_void<It>::type;
@@ -743,16 +745,40 @@ class stride_counting_iterator {
743745 std::conditional_t <std::input_iterator<It>, std::input_iterator_tag,
744746 /* else */ std::output_iterator_tag
745747 >>>>>;
748+ using iterator_category = iterator_concept;
746749
747750 stride_counting_iterator () requires std::default_initializable<It> = default ;
748751
749752 constexpr explicit stride_counting_iterator (It const & it) : base_(base(it)) { }
750753
754+ constexpr explicit stride_counting_iterator (
755+ It const & it, StrideCountType* stride_count, StrideDisplacementType* stride_displacement)
756+ : base_(base(it)), stride_count_(stride_count), stride_displacement_(stride_displacement) {}
757+
758+ constexpr stride_counting_iterator (const stride_counting_iterator& o) { *this = o; }
759+ constexpr stride_counting_iterator (stride_counting_iterator&& o) { *this = o; }
760+
761+ constexpr stride_counting_iterator& operator =(const stride_counting_iterator& o) {
762+ base_ = o.base_ ;
763+ // if memory backing count is owned by the object, copy values
764+ if (o.stride_count_ == &o.stride_count_default_ ) {
765+ assert (o.stride_displacement_ == &o.stride_displacement_default_ );
766+ *stride_count_ = *o.stride_count_ ;
767+ *stride_displacement_ = *o.stride_displacement_ ;
768+ return *this ;
769+ }
770+ // otherwise share the same externally-owned variables
771+ stride_count_ = o.stride_count_ ;
772+ stride_displacement_ = o.stride_displacement_ ;
773+ return *this ;
774+ }
775+ constexpr stride_counting_iterator& operator =(stride_counting_iterator&& o) { return *this = o; }
776+
751777 friend constexpr It base (stride_counting_iterator const & it) { return It (it.base_ ); }
752778
753- constexpr difference_type stride_count () const { return stride_count_; }
779+ constexpr StrideCountType stride_count () const { return * stride_count_; }
754780
755- constexpr difference_type stride_displacement () const { return stride_displacement_; }
781+ constexpr StrideDisplacementType stride_displacement () const { return * stride_displacement_; }
756782
757783 constexpr decltype (auto ) operator*() const { return *It (base_); }
758784
@@ -761,8 +787,8 @@ class stride_counting_iterator {
761787 constexpr stride_counting_iterator& operator ++() {
762788 It tmp (base_);
763789 base_ = base (++tmp);
764- ++stride_count_;
765- ++stride_displacement_;
790+ ++* stride_count_;
791+ ++* stride_displacement_;
766792 return *this ;
767793 }
768794
@@ -781,8 +807,8 @@ class stride_counting_iterator {
781807 {
782808 It tmp (base_);
783809 base_ = base (--tmp);
784- ++stride_count_;
785- --stride_displacement_;
810+ ++* stride_count_;
811+ --* stride_displacement_;
786812 return *this ;
787813 }
788814
@@ -799,8 +825,8 @@ class stride_counting_iterator {
799825 {
800826 It tmp (base_);
801827 base_ = base (tmp += n);
802- ++stride_count_;
803- ++stride_displacement_;
828+ ++* stride_count_;
829+ ++* stride_displacement_;
804830 return *this ;
805831 }
806832
@@ -809,8 +835,8 @@ class stride_counting_iterator {
809835 {
810836 It tmp (base_);
811837 base_ = base (tmp -= n);
812- ++stride_count_;
813- --stride_displacement_;
838+ ++* stride_count_;
839+ --* stride_displacement_;
814840 return *this ;
815841 }
816842
@@ -873,8 +899,11 @@ class stride_counting_iterator {
873899
874900private:
875901 decltype (base(std::declval<It>())) base_;
876- difference_type stride_count_ = 0 ;
877- difference_type stride_displacement_ = 0 ;
902+ StrideCountType stride_count_default_ = 0 ;
903+ StrideDisplacementType stride_displacement_default_ = 0 ;
904+
905+ StrideCountType* stride_count_ = &stride_count_default_;
906+ StrideDisplacementType* stride_displacement_ = &stride_displacement_default_;
878907};
879908template <class It >
880909stride_counting_iterator (It) -> stride_counting_iterator<It>;
0 commit comments