@@ -738,35 +738,49 @@ class counting_iterator {
738
738
T &operator *() const { return blackhole_; }
739
739
};
740
740
741
+ template <typename OutputIt>
742
+ class truncating_iterator_base {
743
+ protected:
744
+ OutputIt out_;
745
+ std::size_t limit_;
746
+ std::size_t count_;
747
+
748
+ truncating_iterator_base (OutputIt out, std::size_t limit)
749
+ : out_(out), limit_(limit), count_(0 ) {}
750
+
751
+ public:
752
+ typedef std::output_iterator_tag iterator_category;
753
+ typedef void difference_type;
754
+ typedef void pointer;
755
+ typedef void reference;
756
+ typedef truncating_iterator_base _Unchecked_type; // Mark iterator as checked.
757
+
758
+ OutputIt base () const { return out_; }
759
+ std::size_t count () const { return count_; }
760
+ };
761
+
741
762
// An output iterator that truncates the output and counts the number of objects
742
763
// written to it.
764
+ template <typename OutputIt, typename Enable = typename std::is_void<
765
+ typename std::iterator_traits<OutputIt>::value_type>::type>
766
+ class truncating_iterator ;
767
+
743
768
template <typename OutputIt>
744
- class truncating_iterator {
745
- private:
769
+ class truncating_iterator <OutputIt, std::false_type>:
770
+ public truncating_iterator_base<OutputIt> {
746
771
typedef std::iterator_traits<OutputIt> traits;
747
772
748
- OutputIt out_;
749
- std::size_t limit_;
750
- std::size_t count_;
751
773
mutable typename traits::value_type blackhole_;
752
774
753
775
public:
754
- typedef std::output_iterator_tag iterator_category;
755
776
typedef typename traits::value_type value_type;
756
- typedef typename traits::difference_type difference_type;
757
- typedef typename traits::pointer pointer;
758
- typedef typename traits::reference reference;
759
- typedef truncating_iterator _Unchecked_type; // Mark iterator as checked.
760
777
761
778
truncating_iterator (OutputIt out, std::size_t limit)
762
- : out_(out), limit_(limit), count_(0 ) {}
763
-
764
- OutputIt base () const { return out_; }
765
- std::size_t count () const { return count_; }
779
+ : truncating_iterator_base<OutputIt>(out, limit) {}
766
780
767
781
truncating_iterator& operator ++() {
768
- if (count_++ < limit_)
769
- ++out_;
782
+ if (this -> count_ ++ < this -> limit_ )
783
+ ++this -> out_ ;
770
784
return *this ;
771
785
}
772
786
@@ -776,7 +790,31 @@ class truncating_iterator {
776
790
return it;
777
791
}
778
792
779
- reference operator *() const { return count_ < limit_ ? *out_ : blackhole_; }
793
+ value_type& operator *() const {
794
+ return this ->count_ < this ->limit_ ? *this ->out_ : blackhole_;
795
+ }
796
+ };
797
+
798
+ template <typename OutputIt>
799
+ class truncating_iterator <OutputIt, std::true_type>:
800
+ public truncating_iterator_base<OutputIt> {
801
+ public:
802
+ typedef typename OutputIt::container_type::value_type value_type;
803
+
804
+ truncating_iterator (OutputIt out, std::size_t limit)
805
+ : truncating_iterator_base<OutputIt>(out, limit) {}
806
+
807
+ truncating_iterator& operator =(value_type val) {
808
+ if (this ->count_ ++ < this ->limit_ )
809
+ this ->out_ = val;
810
+ return *this ;
811
+ }
812
+
813
+ truncating_iterator& operator ++() { return *this ; }
814
+
815
+ truncating_iterator& operator ++(int ) { return *this ; }
816
+
817
+ truncating_iterator& operator *() { return *this ; }
780
818
};
781
819
782
820
// Returns true if value is negative, false otherwise.
0 commit comments