diff --git a/src/swcio.hpp b/src/swcio.hpp
index ba52720a7f1852c88cb60ae51b0f1aee9c10f9b9..6b5db68dd913db031fe07bd6862d1cae7d6e1d97 100644
--- a/src/swcio.hpp
+++ b/src/swcio.hpp
@@ -2,6 +2,7 @@
 
 #include <exception>
 #include <iostream>
+#include <iterator>
 #include <string>
 #include <vector>
 
@@ -60,6 +61,16 @@ public:
     cell_record(const cell_record &other) = default;
     cell_record &operator=(const cell_record &other) = default;
 
+    bool strict_equals(const cell_record &other)
+    {
+        return id_ == other.id_ &&
+            x_ == other.x_ &&
+            y_ == other.y_ &&
+            z_ == other.z_ &&
+            r_ == other.r_ &&
+            parent_id_ == other.parent_id_;
+    }
+
     // Equality and comparison operators
     friend bool operator==(const cell_record &lhs,
                            const cell_record &rhs)
@@ -151,6 +162,7 @@ private:
     id_type parent_id_; // cell parent's id
 };
 
+
 class swc_parse_error : public std::runtime_error
 {
 public:
@@ -200,5 +212,103 @@ std::istream &operator>>(std::istream &is, cell_record &cell);
 //
 std::vector<cell_record> swc_read_cells(std::istream &is);
 
+class cell_record_stream_iterator :
+        public std::iterator<std::forward_iterator_tag, cell_record>
+{
+public:
+    struct eof_tag { };
+
+    cell_record_stream_iterator(std::istream &is)
+        : is_(is)
+        , eof_(false)
+    {
+        read_next_record();
+    }
+
+    cell_record_stream_iterator(std::istream &is, eof_tag)
+        : is_(is)
+        , eof_(true)
+    { }
+
+
+    cell_record_stream_iterator &operator++()
+    {
+        if (eof_) {
+            throw std::out_of_range("attempt to read past eof");
+        }
+
+        read_next_record();
+        return *this;
+    }
+
+    cell_record_stream_iterator operator++(int);
+
+    value_type operator*()
+    {
+        return curr_record_;
+    }
+
+    bool operator==(const cell_record_stream_iterator &other)
+    {
+        if (eof_ && other.eof_) {
+            return true;
+        } else {
+            return curr_record_.strict_equals(other.curr_record_);
+        }
+    }
+
+    bool operator!=(const cell_record_stream_iterator &other)
+    {
+        return !(*this == other);
+    }
+
+private:
+    void read_next_record()
+    {
+        parser_.parse_record(is_, curr_record_);
+        if (is_.eof()) {
+            eof_ = true;
+        }
+    }
+
+    std::istream &is_;
+    swc_parser parser_;
+    cell_record curr_record_;
+
+    // indicator of eof; we need a way to define an end() iterator without
+    // seeking to the end of file
+    bool eof_;
+};
+
+
+class cell_record_range_raw
+{
+public:
+    using value_type     = cell_record;
+    using reference      = value_type &;
+    using const_referene = const value_type &;
+    using iterator       = cell_record_stream_iterator;
+    using const_iterator = const cell_record_stream_iterator;
+
+    cell_record_range_raw(std::istream &is)
+        : is_(is)
+    { }
+
+    iterator begin()
+    {
+        return cell_record_stream_iterator(is_);
+    }
+
+    iterator end()
+    {
+        iterator::eof_tag eof;
+        return cell_record_stream_iterator(is_, eof);
+    }
+
+private:
+    std::istream &is_;
+};
+
+
 }   // end of nestmc::io
 }   // end of nestmc
diff --git a/tests/test_swcio.cpp b/tests/test_swcio.cpp
index a3a7336a8716877cb2a6bc084b4b866a9b58a005..2ca3563abdf6b412a9a14ac3cdd67802fcfc5f92 100644
--- a/tests/test_swcio.cpp
+++ b/tests/test_swcio.cpp
@@ -296,3 +296,25 @@ TEST(swc_parser, input_cleaning)
         
     }
 }
+
+TEST(cell_record_ranges, raw)
+{
+    using namespace nestmc::io;
+
+    {
+        std::stringstream is;
+
+        // Check valid usage
+        is << "1 1 14.566132 34.873772 7.857000 0.717830 -1\n";
+        is << "2 1 14.566132 34.873772 7.857000 0.717830 1\n";
+        is << "3 1 14.566132 34.873772 7.857000 0.717830 1\n";
+        is << "4 1 14.566132 34.873772 7.857000 0.717830 1\n";
+
+        std::vector<cell_record> cells;
+        for (auto &&c : cell_record_range_raw(is)) {
+            cells.push_back(c);
+        }
+
+        EXPECT_EQ(4, cells.size());
+    }
+}