<commit_before>#ifndef LOOP_PATH_H
#define LOOP_PATH_H

#include <vector>
#include "libthing/Vector2.h"
#include "libthing/LineSegment2.h"

namespace mgl {

typedef libthing::Vector2 PointType;

typedef std::vector<PointType> PointList;
typedef std::vector<PointType> VectorList;


/*!
 * /brief An open ended path
 * A 2d path of points with a defined beginning and end, with no assumption of
 * an interior. Intended to be an extruded path in real space with suspended
 * points.
 *
 * This is a read-write object, meant for both constructing a path as well as
 * following it.
 */
class OpenPath {
	/*!
	 * /brief A shallow wrapper around underlying container iterators
	 */
	template <typename BASE>
	class iterator_gen {
	public:
		typedef BASE iterator;
		iterator_gen(BASE b) : base(b) {};

		PointType& operator*() { return *base; }
		PointType* operator->() { return &*base; }
		iterator operator&() const { return base; }
		// ++iterator
		iterator_gen<BASE>& operator++() {
			++base;
			return *this;
		}
		// iterator++
		iterator_gen<BASE> operator++(int) {
			iterator_gen<BASE> iter_copy = *this;
			++*this;
			return iter_copy;
		}
		iterator_gen<BASE>& operator+=(int off) {
			base += off;
			return *this;
		};
		iterator_gen<BASE> operator+(int off) {
			iterator_gen<BASE> iter_copy = *this;
			return iter_copy+=off;
		}
		// --iterator
		iterator_gen<BASE>& operator--() {
			--base;
			return *this;
		}
		// iterator--
		iterator_gen<BASE> operator--(int) {
			iterator_gen<BASE> iter_copy = *this;
			--*this;
			return iter_copy;
		}
		iterator_gen<BASE>& operator-=(int off) {
			return base += (-off);
		}
		iterator_gen<BASE> operator-(int off) {
			return *this + (-off);
		}
		bool operator==(const iterator_gen<BASE>& other) {
			return base == other.base;
		}
		bool operator!=(const iterator_gen<BASE>& other) {
			return !(*this==other);
		}

	private:
		BASE base;
	};

public:
	typedef iterator_gen<PointList::iterator> iterator;
	typedef iterator_gen<PointList::reverse_iterator> reverse_iterator;
	typedef iterator entry_iterator;

	OpenPath() : endpoints(2) {};
	/*! Get an iterator from the first point of the path */
	iterator fromStart() { return iterator(points.begin()); };
	/*! Get an iterator from the last point of the path	 */
	reverse_iterator fromEnd() { return reverse_iterator(points.rbegin()); };

	iterator end() { return iterator(points.end()); };
	reverse_iterator rend() { return reverse_iterator(points.rend()); };

	/*! Add points to the end of a path.  This makes copies of the points.
	 *  /param first iterator to the first point to append
	 *  /param end stop iterating here
	 */
	template <typename ITER>
	void appendPoints(ITER first, ITER end) {
		for (; first != end; ++first)
			appendPoint(*first);
	}

	/*! Add a single point to the end of a path. This copies the point
	 *  /param point value to be appended
	 */
	void appendPoint(const PointType &point) {
		points.push_back(point);
	}

	/*! Add points to the beginning of a path. This makes coppies of the points.
	 *  /param first iterator to the first point to append
	 *  /param end stop iterating here
	 */
	template <typename ITER>
	void prependPoints(ITER first, ITER end) {
		for (; first != end; ++first) 
			prependPoint(*first);
	}
		
	/*! Add a single point to the beginning of a path. This copies the point
	 *  /param point value to be appended
	 */
	void prependPoint(const PointType &point) {
		points.insert(points.begin(), point);
	}

	/*! Retrieve the LineSegment2 in the path that starts with a provided point.
	 *  This creates a new LineSegment2 value
	 *  /param location iterator pointing to the first endpoint of the segment
	 *  /return The line segment starting with the point at location, or a zero
	 *          length segment if this is the last point in the path
	 */
	template <typename ITER>
	libthing::LineSegment2 segmentAfterPoint(ITER &beginning) {
		ITER endpoint = beginning;
		++endpoint;

		if (isEnd(endpoint))
			//0 len segment if we're at the last point
			return libthing::LineSegment2(*beginning, *beginning);

		else
			return libthing::LineSegment2(*beginning, *endpoint);
	}

	/*! Find points you can start extrusion on for this path.  For an
	 *  OpenPath, this gives you the endpoints.
	 *  /return iterator for all the valid staring points
	 */
	entry_iterator getEntryPoints() {
		setEndPoints();
		return iterator(endpoints.begin());
	}

	PointType& getExitPoint(PointType entry) {
		setEndPoints();
		if (endpoints[0] == entry) {
			return endpoints[1];
		}
		else if (endpoints[1] == entry) {
			return endpoints[0];
		}
		else {
			throw Exception("Not a valid entry point");
		}
	}

	/*! Find points that are suspended by material underneath.
	 *  This is not implemented as the suspended property is not implemented.
	 *  /return An iterator to retrieve all suspended points, currently
	            retrieves all points
	 */
	iterator getSuspendedPoints() { return fromStart(); }; //stub
	
private:
	bool isEnd(iterator i) {
		return i == end();
	}

	bool isEnd(reverse_iterator i) {
		return i == rend();
	}

	void setEndPoints() {
		endpoints[0] = points.front();
		endpoints[1] = points.back();
	}		

	PointList points;
	PointList endpoints;
};


/*! /brief A closed loop
 *  A 2d path that has no beginning or end, connects around to itself, and has
 *  an interior.
 */
class Loop {
public:
	class PointNormal;
	typedef std::vector<PointNormal> PointNormalList;
private:
	template <typename BASE>
	class iterator_gen {
	public:
		typedef BASE iterator;
		iterator_gen(iterator i, iterator b, iterator e) : 
				base(i), begin(b), end(e) {};
		iterator_gen(const iterator_gen& orig) : 
				base(orig.base), begin(orig.begin), end(orig.end) {}
		iterator_gen<BASE>& operator=(const iterator_gen<BASE>& orig) {
			base = orig.base;
			begin = orig.begin;
			end = orig.end;
		}
		
		PointNormal& operator*() { return *base; }
		PointNormal* operator->() { return &*base; }
		iterator operator&() const { return base; }
		// ++iterator
		iterator_gen<BASE>& operator++() {
			if(base != end) {
				++base;
				if (base == end) {
					base = begin;
				}
			}
			
			return *this;
		}
		// iterator++
		iterator_gen<BASE> operator++(int) {
			iterator_gen<BASE> iter_copy = *this;
			return ++iter_copy;
		}
		// --iterator
		iterator_gen<BASE>& operator--() {
			if(base != end) {
				if(base == begin){
					base = end;
				}
				--base;
			}
			return *this;
		}
		// iterator--
		iterator_gen<BASE> operator--(int) {
			iterator_gen<BASE> iter_copy = *this;
			return --iter_copy;
		}
		iterator_gen<BASE> makeBegin() { 
			return iterator_gen(begin, begin, end); 
		}
		iterator_gen<BASE> makeEnd() { 
			return iterator_gen(end, begin, end); 
		}
		
		bool operator==(const iterator_gen& other) const {
			return base == other.base;
		}
		bool operator!=(const iterator_gen& other) const {
			return !(*this == other);
		}
		bool isBegin() const { return base == begin; }
		bool isEnd() const { return base == end; }
	protected:
		iterator base;
		iterator begin;
		iterator end;
	};
	
	/*! Specialization of iterator_gen for entry points
	 *
	 */
	template <typename BASE>
	class iterator_entry_gen : public iterator_gen<BASE> {
		typedef typename iterator_gen<BASE>::iterator iterator;
	public:
		iterator_entry_gen(iterator i, iterator b, iterator e) : 
				iterator_gen<BASE>(i, b, e) {}
		const PointType& operator*() { 
			return iterator_gen<BASE>::base->getPoint(); 
		}
		const PointType* operator->() { 
			return &(iterator_gen<BASE>::base->getPoint()); 
		}
		// ++iterator	
		iterator_entry_gen<BASE>& operator++() {
			++iterator_gen<BASE>::base;
			return *this;
		}
		// iterator++
		iterator_entry_gen<BASE> operator++(int) {
			iterator_entry_gen<BASE> iter_copy = *this;
			++*this;
			return iter_copy;
		}
		// --iterator
		iterator_entry_gen<BASE>& operator--() {
			--iterator_gen<BASE>::base;
			return *this;
		}
		iterator_entry_gen<BASE>& operator--(int) {
			iterator_entry_gen<BASE> iter_copy = *this;
			--*this;
			return iter_copy;
		}
	};<commit_msg>Modified iterator_entry_gen operator overloads to properly return references and pointers<commit_after>#ifndef LOOP_PATH_H
#define LOOP_PATH_H

#include <vector>
#include "libthing/Vector2.h"
#include "libthing/LineSegment2.h"

namespace mgl {

typedef libthing::Vector2 PointType;

typedef std::vector<PointType> PointList;
typedef std::vector<PointType> VectorList;


/*!
 * /brief An open ended path
 * A 2d path of points with a defined beginning and end, with no assumption of
 * an interior. Intended to be an extruded path in real space with suspended
 * points.
 *
 * This is a read-write object, meant for both constructing a path as well as
 * following it.
 */
class OpenPath {
	/*!
	 * /brief A shallow wrapper around underlying container iterators
	 */
	template <typename BASE>
	class iterator_gen {
	public:
		typedef BASE iterator;
		iterator_gen(BASE b) : base(b) {};

		PointType& operator*() { return *base; }
		PointType* operator->() { return &*base; }
		iterator operator&() const { return base; }
		// ++iterator
		iterator_gen<BASE>& operator++() {
			++base;
			return *this;
		}
		// iterator++
		iterator_gen<BASE> operator++(int) {
			iterator_gen<BASE> iter_copy = *this;
			++*this;
			return iter_copy;
		}
		iterator_gen<BASE>& operator+=(int off) {
			base += off;
			return *this;
		};
		iterator_gen<BASE> operator+(int off) {
			iterator_gen<BASE> iter_copy = *this;
			return iter_copy+=off;
		}
		// --iterator
		iterator_gen<BASE>& operator--() {
			--base;
			return *this;
		}
		// iterator--
		iterator_gen<BASE> operator--(int) {
			iterator_gen<BASE> iter_copy = *this;
			--*this;
			return iter_copy;
		}
		iterator_gen<BASE>& operator-=(int off) {
			return base += (-off);
		}
		iterator_gen<BASE> operator-(int off) {
			return *this + (-off);
		}
		bool operator==(const iterator_gen<BASE>& other) {
			return base == other.base;
		}
		bool operator!=(const iterator_gen<BASE>& other) {
			return !(*this==other);
		}

	private:
		BASE base;
	};

public:
	typedef iterator_gen<PointList::iterator> iterator;
	typedef iterator_gen<PointList::reverse_iterator> reverse_iterator;
	typedef iterator entry_iterator;

	OpenPath() : endpoints(2) {};
	/*! Get an iterator from the first point of the path */
	iterator fromStart() { return iterator(points.begin()); };
	/*! Get an iterator from the last point of the path	 */
	reverse_iterator fromEnd() { return reverse_iterator(points.rbegin()); };

	iterator end() { return iterator(points.end()); };
	reverse_iterator rend() { return reverse_iterator(points.rend()); };

	/*! Add points to the end of a path.  This makes copies of the points.
	 *  /param first iterator to the first point to append
	 *  /param end stop iterating here
	 */
	template <typename ITER>
	void appendPoints(ITER first, ITER end) {
		for (; first != end; ++first)
			appendPoint(*first);
	}

	/*! Add a single point to the end of a path. This copies the point
	 *  /param point value to be appended
	 */
	void appendPoint(const PointType &point) {
		points.push_back(point);
	}

	/*! Add points to the beginning of a path. This makes coppies of the points.
	 *  /param first iterator to the first point to append
	 *  /param end stop iterating here
	 */
	template <typename ITER>
	void prependPoints(ITER first, ITER end) {
		for (; first != end; ++first) 
			prependPoint(*first);
	}
		
	/*! Add a single point to the beginning of a path. This copies the point
	 *  /param point value to be appended
	 */
	void prependPoint(const PointType &point) {
		points.insert(points.begin(), point);
	}

	/*! Retrieve the LineSegment2 in the path that starts with a provided point.
	 *  This creates a new LineSegment2 value
	 *  /param location iterator pointing to the first endpoint of the segment
	 *  /return The line segment starting with the point at location, or a zero
	 *          length segment if this is the last point in the path
	 */
	template <typename ITER>
	libthing::LineSegment2 segmentAfterPoint(ITER &beginning) {
		ITER endpoint = beginning;
		++endpoint;

		if (isEnd(endpoint))
			//0 len segment if we're at the last point
			return libthing::LineSegment2(*beginning, *beginning);

		else
			return libthing::LineSegment2(*beginning, *endpoint);
	}

	/*! Find points you can start extrusion on for this path.  For an
	 *  OpenPath, this gives you the endpoints.
	 *  /return iterator for all the valid staring points
	 */
	entry_iterator getEntryPoints() {
		setEndPoints();
		return iterator(endpoints.begin());
	}

	PointType& getExitPoint(PointType entry) {
		setEndPoints();
		if (endpoints[0] == entry) {
			return endpoints[1];
		}
		else if (endpoints[1] == entry) {
			return endpoints[0];
		}
		else {
			throw Exception("Not a valid entry point");
		}
	}

	/*! Find points that are suspended by material underneath.
	 *  This is not implemented as the suspended property is not implemented.
	 *  /return An iterator to retrieve all suspended points, currently
	            retrieves all points
	 */
	iterator getSuspendedPoints() { return fromStart(); }; //stub
	
private:
	bool isEnd(iterator i) {
		return i == end();
	}

	bool isEnd(reverse_iterator i) {
		return i == rend();
	}

	void setEndPoints() {
		endpoints[0] = points.front();
		endpoints[1] = points.back();
	}		

	PointList points;
	PointList endpoints;
};


/*! /brief A closed loop
 *  A 2d path that has no beginning or end, connects around to itself, and has
 *  an interior.
 */
class Loop {
public:
	class PointNormal;
	typedef std::vector<PointNormal> PointNormalList;
private:
	template <typename BASE>
	class iterator_gen {
	public:
		typedef BASE iterator;
		iterator_gen(iterator i, iterator b, iterator e) : 
				base(i), begin(b), end(e) {};
		iterator_gen(const iterator_gen& orig) : 
				base(orig.base), begin(orig.begin), end(orig.end) {}
		iterator_gen<BASE>& operator=(const iterator_gen<BASE>& orig) {
			base = orig.base;
			begin = orig.begin;
			end = orig.end;
		}
		
		PointNormal& operator*() { return *base; }
		PointNormal* operator->() { return &*base; }
		iterator operator&() const { return base; }
		// ++iterator
		iterator_gen<BASE>& operator++() {
			if(base != end) {
				++base;
				if (base == end) {
					base = begin;
				}
			}
			
			return *this;
		}
		// iterator++
		iterator_gen<BASE> operator++(int) {
			iterator_gen<BASE> iter_copy = *this;
			return ++iter_copy;
		}
		// --iterator
		iterator_gen<BASE>& operator--() {
			if(base != end) {
				if(base == begin){
					base = end;
				}
				--base;
			}
			return *this;
		}
		// iterator--
		iterator_gen<BASE> operator--(int) {
			iterator_gen<BASE> iter_copy = *this;
			return --iter_copy;
		}
		iterator_gen<BASE> makeBegin() { 
			return iterator_gen(begin, begin, end); 
		}
		iterator_gen<BASE> makeEnd() { 
			return iterator_gen(end, begin, end); 
		}
		
		bool operator==(const iterator_gen& other) const {
			return base == other.base;
		}
		bool operator!=(const iterator_gen& other) const {
			return !(*this == other);
		}
		bool isBegin() const { return base == begin; }
		bool isEnd() const { return base == end; }
	protected:
		iterator base;
		iterator begin;
		iterator end;
	};
	
	/*! Specialization of iterator_gen for entry points
	 *
	 */
	template <typename BASE>
	class iterator_entry_gen : public iterator_gen<BASE> {
		typedef typename iterator_gen<BASE>::iterator iterator;
	public:
		iterator_entry_gen(iterator i, iterator b, iterator e) : 
				iterator_gen<BASE>(i, b, e) {}
		const PointType& operator*() { 
			return iterator_gen<BASE>::base->getPoint(); 
		}
		const PointType* operator->() { 
			return &(this->operator*());
		}
		// ++iterator	
		iterator_entry_gen<BASE>& operator++() {
			++iterator_gen<BASE>::base;
			return *this;
		}
		// iterator++
		iterator_entry_gen<BASE> operator++(int) {
			iterator_entry_gen<BASE> iter_copy = *this;
			++*this;
			return iter_copy;
		}
		// --iterator
		iterator_entry_gen<BASE>& operator--() {
			--iterator_gen<BASE>::base;
			return *this;
		}
		iterator_entry_gen<BASE>& operator--(int) {
			iterator_entry_gen<BASE> iter_copy = *this;
			--*this;
			return iter_copy;
		}
	};
{'fraction_non_alphanumeric': 0.12780794865465317, 'fraction_numerical': 0.002221673660824488, 'mean_word_length': 3.5202231520223153, 'pattern_counts': {'":': 0, '<': 98, '<?xml version=': 0, '>': 108, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3906316', 'n_tokens_mistral': 5781, 'n_tokens_neox': 5092, 'n_words': 1577}