Skip to content

Commit

Permalink
Merge pull request #161 from winner245/input_iterator
Browse files Browse the repository at this point in the history
Add basic  input iterator support
  • Loading branch information
Alinshans authored Oct 27, 2024
2 parents acc07e0 + 4dda5db commit f86437e
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 0 deletions.
4 changes: 4 additions & 0 deletions MyTinySTL/iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ struct has_iterator_cat_of
template <class T, class U>
struct has_iterator_cat_of<T, U, false> : public m_false_type {};

template <class Iter>
struct is_exactly_input_iterator : public m_bool_constant<has_iterator_cat_of<Iter, input_iterator_tag>::value &&
!has_iterator_cat_of<Iter, forward_iterator_tag>::value> {};

template <class Iter>
struct is_input_iterator : public has_iterator_cat_of<Iter, input_iterator_tag> {};

Expand Down
81 changes: 81 additions & 0 deletions MyTinySTL/stream_iterator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#ifndef MYTINYSTL_STREAM_ITERATOR_H_
#define MYTINYSTL_STREAM_ITERATOR_H_

#include "basic_string.h"

namespace mystl
{

template<typename T, typename CharT = char,
typename Traits = std::char_traits<CharT>, typename Dist = ptrdiff_t>
class istream_iterator
: public iterator<input_iterator_tag, T, Dist, const T*, const T&>
{
public:
using char_type = CharT;
using traits_type = Traits;
using istream_type = std::basic_istream<CharT, Traits>;

istream_iterator() /* noexcept(std::is_nothrow_default_constructible<T>::value) */
: m_stream{nullptr}, m_value{} {}

istream_iterator(istream_type& is)
: m_stream{std::addressof(is)}
{ read(); }

istream_iterator(const istream_iterator& other) /* noexcept(std::is_nothrow_copy_constructible<T>::value) */
= default; // memberwise copy

istream_iterator& operator=(const istream_iterator&) = default; // memberwise copy-asgn

~istream_iterator() = default;

const T& operator*() const noexcept {
MYSTL_DEBUG(m_stream != nullptr);
return m_value;
}

const T* operator->() const noexcept {
return std::addressof(*this);
}

istream_iterator& operator++() {
MYSTL_DEBUG(m_stream != nullptr);
read();
return *this;
}

istream_iterator operator++(int) {
auto tmp = *this;
++*this;
return tmp;
}

private:
istream_type* m_stream;
T m_value;

void read() {
if (m_stream && !(*m_stream >> m_value)) { // m_stream 有效且读到 EOS
m_stream = nullptr;
}
}

friend bool operator==(const istream_iterator& lhs, const istream_iterator& rhs) {
return lhs.m_stream == rhs.m_stream;
}

friend bool operator!=(const istream_iterator& lhs, const istream_iterator& rhs) {
return lhs.m_stream != rhs.m_stream;
}
};


// TODO
// template<typename T, typename CharT = char,
// typename Traits = char_traits<CharT> >
// class ostream_iterator : public iterator<output_iterator_tag, void, void, void, void> {};
}


#endif
42 changes: 42 additions & 0 deletions Test/iterator_test.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#ifndef MYTINYSTL_ITERATOR_TEST_H_
#define MYTINYSTL_ITERATOR_TEST_H_

#include "test.h"
#include "../MyTinySTL/iterator.h"
#include "../MyTinySTL/stream_iterator.h"

namespace mystl
{
namespace test
{
namespace iterator_test
{

void stream_iterator_test()
{
std::cout << "[===============================================================]\n";
std::cout << "[------------- Run iterator test : stream_iterator--------------]\n";
std::cout << "[-------------------------- API test ---------------------------]\n";

static_assert(mystl::is_exactly_input_iterator<mystl::istream_iterator<int>>::value,
"istream_iterator must have input_iterator_tag)");

std::istringstream is("1 2 3");
mystl::istream_iterator<int> first{is}, last;
std::cout << mystl::distance(first, last) << '\n';

std::istringstream istream("1 2 3 4 5 6");
mystl::istream_iterator<int> beg{istream}, end;
for (; beg != end; ++beg) {
std::cout << *beg << " ";
}
std::cout << '\n';

PASSED;
}

} // namespace stream_iterator_test
} // namespace test
} // namespace mystl
#endif // !MYTINYSTL_STREAM_ITERATOR_TEST_H_

2 changes: 2 additions & 0 deletions Test/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "unordered_map_test.h"
#include "unordered_set_test.h"
#include "string_test.h"
#include "iterator_test.h"

int main()
{
Expand All @@ -29,6 +30,7 @@ int main()

RUN_ALL_TESTS();
algorithm_performance_test::algorithm_performance_test();
iterator_test::stream_iterator_test();
vector_test::vector_test();
list_test::list_test();
deque_test::deque_test();
Expand Down

0 comments on commit f86437e

Please sign in to comment.