From 8f9682743028cd64d7e478c5349173f7e7473ae7 Mon Sep 17 00:00:00 2001 From: Daniel Fiser Date: Thu, 13 Sep 2007 11:06:02 +0200 Subject: [PATCH] Hunk class, VectorPointerIterator template Created new class called Hunk with testsuite. Created new template VectorPointerIterator for iterators over vectors of pointers to some type. This dereferenced iterator returns copy of containing type not pointer to type. --- Makefile | 2 +- hunk.cpp | 37 ++++++++++++++++++++++++++++++++++++ hunk.h | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ tests/Makefile | 7 ++++--- tests/hunk.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/main.cpp | 2 ++ tests/text.cpp | 4 ++++ text.h | 18 +++--------------- utils.h | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 212 insertions(+), 19 deletions(-) create mode 100644 hunk.cpp create mode 100644 hunk.h create mode 100644 tests/hunk.cpp create mode 100644 utils.h diff --git a/Makefile b/Makefile index d23a00b..142e905 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ QT_INCLUDE = -DQT_SHARED -I/opt/qt4/include -I/opt/qt4/include/QtCore QT_LIBS = -lQtCore -L/opt/qt4/lib/ -lz -lm -pthread -lgthread-2.0 -lrt \ -lglib-2.0 -lpthread -ldl -all: text.o snippet.o +all: text.o snippet.o hunk.o %.o: %.cpp %.h $(CC) $(CXXFLAGS) $(DEBUGFLAGS) $(QT_INCLUDE) -c -o $@ $< diff --git a/hunk.cpp b/hunk.cpp new file mode 100644 index 0000000..31ee7bf --- /dev/null +++ b/hunk.cpp @@ -0,0 +1,37 @@ +#include "hunk.h" +using namespace std; + +Hunk::iterator Hunk::begin() const +{ + Hunk::iterator iter; + iter.it = _snippets.begin(); + return iter; +} +Hunk::iterator Hunk::end() const +{ + Hunk::iterator iter; + iter.it = _snippets.end(); + return iter; +} + +//private: +void Hunk::_copy(const Hunk &h) +{ + _original_from_line = h._original_from_line; + _modified_from_line = h._modified_from_line; + + vector::const_iterator it = h._snippets.begin(); + vector::const_iterator it_end = h._snippets.end(); + for(;it != it_end; it++){ + _snippets.push_back(new Snippet(**it)); + } +} + +void Hunk::_free() +{ + vector::const_iterator it = _snippets.begin(); + vector::const_iterator it_end = _snippets.end(); + for(;it != it_end; it++){ + delete *it; + } +} diff --git a/hunk.h b/hunk.h new file mode 100644 index 0000000..a73fd36 --- /dev/null +++ b/hunk.h @@ -0,0 +1,51 @@ +#ifndef _HUNK_H_ +#define _HUNK_H_ + +#include + +#include "snippet.h" +#include "utils.h" + + +/** + * This class describes a hunk of changes from diff. + * Hunk is aggregation of snippets. + */ +class Hunk{ + private: + std::vector _snippets;//! list of snippets + int _original_from_line;//! line on which begin changes in original file + int _modified_from_line;//! line on which begin changes in modified file + + void _copy(const Hunk &); + void _free(); + public: + class iterator; // front declaration + + Hunk(const int original_from, const int modified_from) : + _original_from_line(original_from), + _modified_from_line(modified_from){} + Hunk(const Hunk &h){ _copy(h); } + ~Hunk(){ _free(); } + + Hunk &operator=(const Hunk &h){ _free(); _copy(h); return *this; } + + void addSnippet(Snippet *sn){ _snippets.push_back(sn); } + int numSnippets() const { return _snippets.size(); } + + int originalBeginsAt() const { return _original_from_line;} + int modifiedBeginsAt() const { return _modified_from_line;} + + iterator begin() const; + iterator end() const; + + /** + * Iterator over _snippets. + */ + class iterator : public VectorPointerIterator{ + public: + friend iterator Hunk::begin() const; + friend iterator Hunk::end() const; + }; +}; +#endif diff --git a/tests/Makefile b/tests/Makefile index 1c63a30..af28dd8 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -8,9 +8,10 @@ QT_LIBS = -lQtCore -L/opt/qt4/lib/ -lz -lm -pthread -lgthread-2.0 -lrt \ ALLFLAGS = $(CXXFLAGS) $(DEBUGFLAGS) $(QT_FLAGS) ALLLIBS = -lcppu $(QT_LIBS) -TEST_SUITES = text.cpp snippet.cpp -TEST_DEPS = ../text.cpp ../text.h ../snippet.cpp ../snippet.h -OBJS = ../text.o ../snippet.o +TEST_SUITES = text.cpp snippet.cpp hunk.cpp +TEST_DEPS = ../text.cpp ../text.h ../snippet.cpp ../snippet.h ../hunk.cpp \ + ../hunk.h +OBJS = ../text.o ../snippet.o ../hunk.o diff --git a/tests/hunk.cpp b/tests/hunk.cpp new file mode 100644 index 0000000..c2b911e --- /dev/null +++ b/tests/hunk.cpp @@ -0,0 +1,59 @@ +#include +#include "../hunk.h" + + +TEST_CASE(TestCaseHunk); +Text text; +Text text2; +void setUp() +{ + text.addLine(new QString("Line1")); + text.addLine(new QString("Line2")); + text.addLine(new QString("Line3")); + text.addLine(new QString("Line4")); + text.addLine(new QString("Line5")); + + text2.addLine(new QString("L1")); + text2.addLine(new QString("L2")); + text2.addLine(new QString("L3")); + text2.addLine(new QString("L4")); + text2.addLine(new QString("L5")); +} + +void testConstructors() +{ + Hunk hunk(100,200); + Hunk hunk2(hunk); + Hunk hunk3(200,100); + hunk3 = hunk; + + assertEquals(hunk.originalBeginsAt(), hunk2.originalBeginsAt()); + assertEquals(hunk.modifiedBeginsAt(), hunk3.modifiedBeginsAt()); +} + +void testIterators() +{ + Hunk hunk(100,120); + + hunk.addSnippet(new Context(new Text(text))); + hunk.addSnippet(new Added(new Text(text2))); + hunk.addSnippet(new Changed(new Text(text), new Text(text2))); + + Hunk::iterator it = hunk.begin(); + Hunk::iterator it_end = hunk.end(); + assertEquals((*it).original(), Context(new Text(text)).original()); + assertEquals((*it).modified(), Context(new Text(text)).modified()); + + it++; + it++; + assertEquals((*it).original(), Changed(new Text(text), new Text(text2)).original()); + assertEquals((*it).modified(), Changed(new Text(text), new Text(text2)).modified()); + + assertEquals(hunk.numSnippets(), 3); +} + +TESTS{ + REG_TEST(testConstructors); + REG_TEST(testIterators); +} +TEST_CASE_END; diff --git a/tests/main.cpp b/tests/main.cpp index 7bb34f5..b9a0478 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -1,9 +1,11 @@ #include "text.cpp" #include "snippet.cpp" +#include "hunk.cpp" TEST_SUITE(TestSuiteAll); REG(TestCaseText); REG(TestCaseSnippet); + REG(TestCaseHunk); TEST_SUITE_END; int main(int argc, char *argv[]) diff --git a/tests/text.cpp b/tests/text.cpp index 904ac22..8e5bde7 100644 --- a/tests/text.cpp +++ b/tests/text.cpp @@ -66,6 +66,10 @@ void testIterator() assertTrue(it-- == --it); it_end = it; assertTrue(it == it_end); + + it = t.begin(); + Text::iterator it2(it); + assertTrue(it2 == it); } TESTS{ diff --git a/text.h b/text.h index 607437a..c368a32 100644 --- a/text.h +++ b/text.h @@ -4,6 +4,8 @@ #include #include +#include "utils.h" + class Text{ private: std::vector _text; @@ -28,22 +30,8 @@ class Text{ iterator begin() const; iterator end() const; - class iterator{ - private: - std::vector::const_iterator it; - + class iterator : public VectorPointerIterator{ public: - iterator(){} - iterator(const iterator &iter) : it(iter.it){} - iterator &operator=(const iterator& iter){ it = iter.it; return *this; } - bool operator==(const iterator& iter){ return it == iter.it; } - bool operator!=(const iterator& iter){ return it != iter.it; } - iterator &operator++(){ it++; return *this; } - iterator &operator++(int){ it++; return *this; } - iterator &operator--(){ it--; return *this; } - iterator &operator--(int){ it--; return *this; } - QString operator*() const{ return **it; } - friend iterator Text::begin() const; friend iterator Text::end() const; }; diff --git a/utils.h b/utils.h new file mode 100644 index 0000000..d2734e6 --- /dev/null +++ b/utils.h @@ -0,0 +1,51 @@ +#ifndef _UTILS_H_ +#define _UTILS_H_ + +#include + +/** + * Iterator for vectors containing pointers to Type. + * Attention: Dereferenced iterator returns copy of the Type + * (not pointer to Type)! + * For usage it should be enough to public inherit from this class and + * declare some friend methods (functions). + * Example: + * + * class Cl{ + * public: + * class iterator; + * + * iterator begin() const; + * iterator end() const; + * + * class iterator : public VectorPointerIterator{ + * public: + * friend iterator Cl::begin() const; + * friend iterator Cl::end() const; + * }; + * }; + * + */ +template +class VectorPointerIterator{ + protected: + typedef typename std::vector::const_iterator iterator_t; + iterator_t it; + + public: + VectorPointerIterator(){} + VectorPointerIterator(const VectorPointerIterator &iter) : it(iter.it){} + virtual VectorPointerIterator + &operator=(const VectorPointerIterator& iter) + { it = iter.it; return *this; } + virtual bool + operator==(const VectorPointerIterator& iter){ return it == iter.it; } + virtual bool + operator!=(const VectorPointerIterator& iter){ return it != iter.it; } + virtual VectorPointerIterator &operator++(){ it++; return *this; } + virtual VectorPointerIterator &operator++(int){ it++; return *this; } + virtual VectorPointerIterator &operator--(){ it--; return *this; } + virtual VectorPointerIterator &operator--(int){ it--; return *this; } + virtual Type operator*() const{ return **it; } +}; +#endif -- 2.11.4.GIT