#include <vector>
#include <stdexcept>
-#include <cstdlib>
#include "misc.h"
/**
- * Stores a gene order permutation and ensures that all genes are present and not duplicated.
+ * Stores a gene order permutation and ensures that all genes are present
+ * and not duplicated.
+ *
+ * It has limited support for acting as an STL container, but still maintaining
+ * the invariant of a permutation starting with 0 and ending with n, with all
+ * genes present.
+ *
* \author Michael Andreen
*/
class GeneOrder{
typedef std::vector<Gene> GeneList;
typedef GeneList::size_type size_type;
+ typedef GeneList::const_iterator iterator;
/**
* Creates a copy of the given gene order
GeneOrder(const GeneOrder& go);
/**
- * Creates a gene order from a given list.
+ * Creates a gene order from a given list, using STL-type iterators.
*
- * \throws invalid_argument if the list is not a valid permutation.
+ * The given permutation needs to contain all genes 1 to n, if 0 is
+ * included it has to be the first item, if it is not present it will
+ * be added automatically. Similarily, if n is not the last item, then
+ * n+1 will be added to the end.
+ *
+ * \param begin iterator to the first element in the list, from begin()
+ * on stl collections and pointer to first item on plain arrays.
+ *
+ * \param end iterator to the element behind the last, from end() in
+ * stl collections or pointer to first element+size on plain arrays.
+ *
+ * \throws std::invalid_argument if the list is not a valid permutation.
*/
template<class T>
GeneOrder(T begin, T end);
/**
* Returns the gene at the given index.
*
- * \throws out_of_range if i is smaller than 0 or too big.
+ * \throws std::out_of_range if i is smaller than 0 or bigger than n.
*/
const Gene& operator[](size_type i) const;
/**
* Returns the size of the permutation.
*/
- int size() const;
+ size_type size() const;
/**
* Returns the vector containing the gene order permutation.
const GeneList& list() const;
/**
- * Reverses an interval and returns the new permutation
+ * Returns the start iterator for the permutation.
+ * To be used with STL style functions.
+ *
+ * \see end
+ */
+ iterator begin() const;
+
+ /**
+ * Returns the end iterator for the permutation.
+ * To be used with STL style functions.
+ *
+ * \see begin
*/
- GeneOrder reverse(size_type i, size_type j) const;
+ iterator end() const;
/**
- * Moves the gene on position i to position j, returning a new permutation
+ * Reverserses the interval [i,j], changing the sign on all elements
+ * affected.
+ *
+ * \throws std::out_of_range if i is smaller than 0 or bigger than n.
*/
- GeneOrder transpos(size_type i, size_type j) const;
+ void reverse(size_type i, size_type j);
+
private:
GeneList _geneorder;
+ /**
+ * pads the permutation with 0 in front and n+1 at the end if needed
+ */
+ void pad();
+
+ /**
+ * Verifies that the permutation starts with 0, ends with n+1 and that all genes i, 0 < i < n+1
+ * are present, without duplication.
+ */
+ void verify();
};
*/
template<typename T>
GeneOrder::GeneOrder(T begin, T end): _geneorder(begin,end){
-
- /*TODO: Pad code, just not sure if I need it all the time.
- if (_geneorder[0] != 0)
- _geneorder.insert(_geneorder.begin(),0);
- if(_geneorder[_geneorder.size()-1] != _geneorder.size() - 1)
- _geneorder.push_back(_geneorder.size());
- */
-
- GeneList genes(_geneorder.size());
- for (GeneList::iterator gene = _geneorder.begin(); gene != _geneorder.end(); ++gene){
- ++genes[std::abs(*gene)];
- }
- for (GeneList::iterator gene = genes.begin(); gene != genes.end(); ++gene){
- if (*gene != 1)
- throw std::invalid_argument("Not all genes are present only 1 time");
- }
+ pad();
+ verify();
}
#endif