1 /*
2 
3   MusicXML Library
4   Copyright (C) 2009  Grame
5 
6   This library is free software; you can redistribute it and/or
7   modify it under the terms of the GNU Lesser General Public
8   License as published by the Free Software Foundation; either
9   version 2.1 of the License, or (at your option) any later version.
10 
11   This library is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   Lesser General Public License for more details.
15 
16   You should have received a copy of the GNU Lesser General Public
17   License along with this library; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 
20   Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
21   research@grame.fr
22 
23 */
24 
25 #ifndef __ringvector__
26 #define __ringvector__
27 
28 #include <vector>
29 
30 namespace guido
31 {
32 
33 //______________________________________________________________________________
34 template <typename T> class fwbwIterator : public std::iterator<std::input_iterator_tag, T>
35 {
36 	protected:
37 		typedef typename std::vector<T>::iterator stdIterator;
38 		stdIterator fIterator, fBegin, fEnd;
39 		bool fForward;
40 
41 	public:
fwbwIterator()42 				 fwbwIterator() : fForward(true) {}
fwbwIterator(const stdIterator & current,const stdIterator & beg,const stdIterator & end)43 				 fwbwIterator(const stdIterator& current, const stdIterator& beg, const stdIterator& end)
44 					: fIterator(current), fBegin(beg), fEnd(end), fForward(current != end) {}
~fwbwIterator()45 		virtual ~fwbwIterator() {}
46 
47 		T operator  *() const	{ return *fIterator; }
48 		T operator ->() const	{ return *fIterator; }
49 
50 		fwbwIterator& operator ++()	{
51 			stdIterator i = fIterator;
52 			if (fForward) {
53 				i++;
54 				if (i == fEnd) {
55 					fIterator--;
56 					fForward = false;
57 				}
58 				else fIterator = i;
59 			}
60 			else {
61 				i--;
62 				if (i == fBegin) {
63 					fIterator--;
64 					fForward = true;
65 				}
66 				else fIterator = i;
67 			}
68 			return *this;
69 		}
70 		fwbwIterator& operator ++(int)	{ return operator ++(); }
71 
72 		//________________________________________________________________________
73 		bool operator ==(const fwbwIterator& i) const		{ return fIterator == i.fIterator; }
74 		bool operator !=(const fwbwIterator& i) const		{ return !(*this == i); }
75 };
76 
77 //______________________________________________________________________________
78 template <typename T> class ringvectorIterator : public std::iterator<std::input_iterator_tag, T>
79 {
80 	protected:
81 		typedef typename std::vector<T>::iterator stdIterator;
82 		stdIterator fIterator, fBegin, fEnd;
83 
84 	public:
ringvectorIterator()85 				 ringvectorIterator() {}
ringvectorIterator(const stdIterator & current,const stdIterator & beg,const stdIterator & end)86 				 ringvectorIterator(const stdIterator& current, const stdIterator& beg, const stdIterator& end)
87 					: fIterator(current), fBegin(beg), fEnd(end) {}
~ringvectorIterator()88 		virtual ~ringvectorIterator() {}
89 
90 		T operator  *() const	{ return *fIterator; }
91 		T operator ->() const	{ return *fIterator; }
92 
93 		ringvectorIterator& operator ++()	{
94 			fIterator++;
95 			if (fIterator== fEnd) fIterator= fBegin;
96 			return *this;
97 		}
98 		ringvectorIterator& operator ++(int)	{ return operator ++(); }
99 
100 		//________________________________________________________________________
101 		bool operator ==(const ringvectorIterator& i) const		{ return fIterator == i.fIterator; }
102 		bool operator !=(const ringvectorIterator& i) const		{ return !(*this == i); }
103 };
104 
105 //______________________________________________________________________________
106 template <typename T> class ringvector : public std::vector<T>
107 {
108 		typedef typename std::vector<T> stdvec;
109 
110 	public:
111 		typedef ringvectorIterator<T>	iterator;
ringvector()112 				 ringvector() {}
~ringvector()113 		virtual ~ringvector() {}
114 
begin()115 		iterator begin()	{ return ringvectorIterator<T>(stdvec::begin(), stdvec::begin(), stdvec::end()); }
end()116 		iterator end()		{ return ringvectorIterator<T>(stdvec::end(), stdvec::begin(), stdvec::end()); }
117 };
118 
119 //______________________________________________________________________________
120 template <typename T> class fwbwvector : public std::vector<T>
121 {
122 		typedef typename std::vector<T> stdvec;
123 
124 	public:
125 		typedef fwbwIterator<T>	iterator;
fwbwvector()126 				 fwbwvector() {}
~fwbwvector()127 		virtual ~fwbwvector() {}
128 
begin()129 		iterator begin()	{ return fwbwIterator<T>(stdvec::begin(), stdvec::begin(), stdvec::end()); }
end()130 		iterator end()		{ return fwbwIterator<T>(stdvec::end(), stdvec::begin(), stdvec::end()); }
131 };
132 
133 }
134 
135 #endif
136