don't inherit Exponent_vector from std::vector<int>

This commit is contained in:
Michael Hemmer 2009-01-04 16:05:03 +00:00
parent 2818272459
commit a377c7ced2
3 changed files with 225 additions and 160 deletions

View File

@ -13,19 +13,17 @@ since negative exponents may appear in intermediate results.
The set of exponent vectors with elementwise
addition forms an {\em Abelian Group}.
Though this class is derived from \ccc{std::vector<int>} the comparison
is changes such that the lexicographic order starts with the last entry.
This reflects the fact that the last entry corresponds
to the last/outermost variable of a multivariate polynomial.
Beside the constructors \ccClassName\ has almost the same interface as an
\ccc{std::vector<int>}. Moreover the comparison is changed such that
the lexicographic order starts the comparison at the last entry.
This reflects the fact that the last entry corresponds to the
outermost variable of a multivariate polynomial.
%\footnote{Should we add a scalar multiplication? }
\ccInclude{CGAL/Exponent_vector.h}
\ccInheritsFrom
\ccc{std::vector<int>}
\ccIsModel
\ccc{Random Access Container}\\

View File

@ -16,8 +16,7 @@
// $Id$
//
//
// Author(s) : Sebastian Limbach
// Michael Hemmer
// Author(s) : Michael Hemmer
//
// ============================================================================
@ -33,93 +32,151 @@
CGAL_BEGIN_NAMESPACE
class Exponent_vector :
public std::vector<int>,
public boost::less_than_comparable1< Exponent_vector >
public boost::less_than_comparable1< Exponent_vector >,
public boost::equality_comparable1< Exponent_vector >
{
typedef std::vector<int> Base;
std::vector<int> v;
public:
Exponent_vector(): Base(){};
typedef Exponent_vector Self;
// OLD CONSTRUCTORS
// Exponent_vector(Base::size_type i): Base(i){};
// Exponent_vector(Base::size_type i, Base::value_type x): Base(i,x){};
// Exponent_vector(int i, int x): Base(i,x){};
// NEW CONSTRUCTORS
Exponent_vector(){};
Exponent_vector(int e0): Base(1) {
(*this)[0]=e0;
};
Exponent_vector(int e0, int e1): Base(2) {
(*this)[0]=e0; (*this)[1]=e1;
};
Exponent_vector(int e0, int e1, int e2): Base(3) {
(*this)[0]=e0; (*this)[1]=e1; (*this)[2]=e2;
};
Exponent_vector(int e0, int e1, int e2, int e3): Base(4) {
(*this)[0]=e0; (*this)[1]=e1; (*this)[2]=e2; (*this)[3]=e3;
};
Exponent_vector(int e0): v(1) {
v[0]=e0;
};
Exponent_vector(int e0, int e1): v(2) {
v[0]=e0; v[1]=e1;
};
Exponent_vector(int e0, int e1, int e2): v(3) {
v[0]=e0; v[1]=e1; v[2]=e2;
};
Exponent_vector(int e0, int e1, int e2, int e3): v(4) {
v[0]=e0; v[1]=e1; v[2]=e2; v[3]=e3;
};
Exponent_vector(const Base& v): Base ( v ){};
Exponent_vector(const Exponent_vector& v): Base ( v ){};
Exponent_vector(const std::vector<int>& v_): v(v_){};
Exponent_vector(const Exponent_vector& ev): v(ev.v){};
template <class InputIterator>
Exponent_vector(InputIterator begin , InputIterator end)
:Base(begin,end){
typedef typename InputIterator::value_type value_type;
BOOST_STATIC_ASSERT(( ::boost::is_same<value_type, int>::value));
template <class InputIterator>
Exponent_vector(InputIterator begin , InputIterator end)
:v(begin,end){
typedef typename std::iterator_traits<InputIterator>::value_type value_type;
BOOST_STATIC_ASSERT(( ::boost::is_same<value_type, int>::value));
}
// mirror vector functions
typedef std::vector<int>::value_type value_type;
typedef std::vector<int>::pointer pointer;
typedef std::vector<int>::const_pointer const_pointer;
typedef std::vector<int>::reference reference;
typedef std::vector<int>::const_reference const_reference;
typedef std::vector<int>::size_type size_type;
typedef std::vector<int>::difference_type difference_type;
typedef std::vector<int>::iterator iterator;
typedef std::vector<int>::const_iterator const_iterator;
typedef std::vector<int>::reverse_iterator reverse_iterator;
typedef std::vector<int>::const_reverse_iterator const_reverse_iterator;
iterator begin(){return v.begin();}
iterator end(){return v.end();}
const_iterator begin() const {return v.begin();}
const_iterator end() const {return v.end();}
reverse_iterator rbegin() {return v.rbegin();}
reverse_iterator rend(){return v.rend();}
const_reverse_iterator rbegin() const {return v.rbegin();}
const_reverse_iterator rend() const {return v.rend();}
size_type size() const {return v.size();}
size_type max_size() const {return v.max_size();}
size_type capacity() const {return v.capacity();}
bool empty() const {return v.empty();}
reference operator[](size_type n) { return v[n]; }
const_reference operator[](size_type n) const {return v[n];}
// vector& operator=(const vector&)
void reserve(size_t s){v.reserve(s);}
reference front(){return v.front();}
const_reference front() const {return v.front();}
reference back() {return v.back();}
const_reference back() const {return v.back();}
void push_back(const int& x) { v.push_back(x);}
void pop_back() {v.pop_back();}
void swap(Self& ev) {v.swap(ev.v);}
iterator insert(iterator pos, const int& x){return v.insert(pos,x);}
template <class InputIterator>
void insert(iterator pos,InputIterator f, InputIterator l){
v.insert(pos,f,l);
}
void insert(iterator pos, size_type n, const int& x){
v.insert(pos,n,x);
}
iterator erase(iterator pos){return v.erase(pos);}
iterator erase(iterator first, iterator last){return v.erase(first,last);}
void clear(){v.clear();}
void resize(size_type n, int t = 0){v.resize(n,t);}
bool operator==(const Self& ev) const { return v == ev.v; }
// this is the actual change
bool operator<( const Exponent_vector& ev ) const {
CGAL_precondition(this->size() == ev.size());
const_reverse_iterator rit1(this->rbegin());
const_reverse_iterator rit2(ev.rbegin());
while(rit1!=this->rend()){
if(*rit1 < *rit2) return true;
if(*rit1 > *rit2) return false;
rit1++; rit2++;
}
CGAL_postcondition(rit1 == this->rend());
CGAL_postcondition(rit2 == ev.rend());
return false;
}
bool operator<( const Exponent_vector& ev ) const {
CGAL_precondition(this->size()==ev.size());
Base::const_reverse_iterator rit1(this->rbegin());
Base::const_reverse_iterator rit2(ev.rbegin());
while(rit1!=this->rend()){
if(*rit1 < *rit2) return true;
if(*rit1 > *rit2) return false;
rit1++; rit2++;
}
CGAL_postcondition(rit1 == this->rend());
CGAL_postcondition(rit2 == ev.rend());
return false;
}
void output_benchmark( std::ostream& os ) const {
os << "( ";
for( unsigned i = 0; i < size(); ++i ) {
if( i != 0 )
os << ", ";
os << at(i);
}
os << " )";
void output_benchmark( std::ostream& os ) const {
os << "( ";
for( unsigned i = 0; i < size(); ++i ) {
if( i != 0 )
os << ", ";
os << v.at(i);
}
os << " )";
}
};
inline bool is_valid(const Exponent_vector& ev) {
Exponent_vector::const_iterator it;
for(it = ev.begin(); it != ev.end();it++){
if (CGAL::is_negative(*it)) return false;
}
return true;
Exponent_vector::const_iterator it;
for(it = ev.begin(); it != ev.end();it++){
if (CGAL::is_negative(*it)) return false;
}
return true;
}
inline std::ostream& operator << (std::ostream& os, const Exponent_vector& ev) {
Exponent_vector::const_iterator it;
os << "(" ;
for(it = ev.begin(); it != ev.end();it++){
if (it == ev.begin()) {
os << *it ;
}
else{
os <<"," << *it ;
}
Exponent_vector::const_iterator it;
os << "(" ;
for(it = ev.begin(); it != ev.end();it++){
if (it == ev.begin()) {
os << *it ;
}
os << ")" ;
return os;
else{
os <<"," << *it ;
}
}
os << ")" ;
return os;
}
CGAL_END_NAMESPACE
namespace std{
template <> void swap(CGAL::Exponent_vector& ev1, CGAL::Exponent_vector& ev2){
ev1.swap(ev2);
}
}
#endif // CGAL_EXPONENT_VECTOR_H

View File

@ -2,98 +2,108 @@
#include <CGAL/basic.h>
#include <cassert>
#include <CGAL/Exponent_vector.h>
#include <boost/concept_check.hpp>
int main() {
typedef CGAL::Exponent_vector T;
CGAL::Exponent_vector ev1,ev2;
assert(ev1.size()==0);
assert(ev2.size()==0);
assert( (ev1==ev2));
assert(!(ev1!=ev2));
assert(!(ev1<ev2));
assert(!(ev1>ev2));
boost::function_requires< boost::DefaultConstructibleConcept<T> >();
boost::function_requires< boost::AssignableConcept<T> >();
boost::function_requires< boost::EqualityComparableConcept<T> >();
boost::function_requires< boost::ComparableConcept<T> >();
boost::function_requires< boost::RandomAccessContainerConcept<T> >();
boost::function_requires< boost::BackInsertionSequenceConcept<T> >();
ev1.push_back(1);
ev1.push_back(0);
ev1.push_back(0);
CGAL::Exponent_vector ev1,ev2;
assert(ev1.size()==0);
assert(ev2.size()==0);
assert( (ev1==ev2));
assert(!(ev1!=ev2));
assert(!(ev1<ev2));
assert(!(ev1>ev2));
ev2.push_back(0);
ev2.push_back(1);
ev2.push_back(0);
ev1.push_back(1);
ev1.push_back(0);
ev1.push_back(0);
assert(!(ev2 == ev1)) ;
assert( (ev2 != ev1)) ;
assert(!(ev2 < ev1)) ;
assert( (ev2 > ev1)) ;
ev2.push_back(0);
ev2.push_back(1);
ev2.push_back(0);
assert(CGAL::is_valid(ev1));
assert(!(ev2 == ev1)) ;
assert( (ev2 != ev1)) ;
assert(!(ev2 < ev1)) ;
assert( (ev2 > ev1)) ;
std::vector<int> vec;
vec.push_back(0); vec.push_back(1); vec.push_back(5);
assert(CGAL::is_valid(ev1));
ev1 = CGAL::Exponent_vector(vec.begin(),vec.end());
assert(ev1[0] == 0);
assert(ev1[1] == 1);
assert(ev1[2] == 5);
std::vector<int> vec;
vec.push_back(0); vec.push_back(1); vec.push_back(5);
// new constructors
// univariate
{
CGAL::Exponent_vector ev(-1);
assert(!CGAL::is_valid(ev));
}
{
CGAL::Exponent_vector ev(0);
assert(CGAL::is_valid(ev));
assert(ev[0] == 0);
}
{
CGAL::Exponent_vector ev(1);
assert(CGAL::is_valid(ev));
assert(ev[0] == 1);
}
ev1 = CGAL::Exponent_vector(vec.begin(),vec.end());
assert(ev1[0] == 0);
assert(ev1[1] == 1);
assert(ev1[2] == 5);
// bivariate
{
CGAL::Exponent_vector ev(0,-1);
assert(!CGAL::is_valid(ev));
}
{
CGAL::Exponent_vector ev(2,1);
assert(CGAL::is_valid(ev));
assert(ev[0] == 2);
assert(ev[1] == 1);
// new constructors
// univariate
{
CGAL::Exponent_vector ev(-1);
assert(!CGAL::is_valid(ev));
}
{
CGAL::Exponent_vector ev(0);
assert(CGAL::is_valid(ev));
assert(ev[0] == 0);
}
{
CGAL::Exponent_vector ev(1);
assert(CGAL::is_valid(ev));
assert(ev[0] == 1);
}
}
// bivariate
{
CGAL::Exponent_vector ev(0,-1);
assert(!CGAL::is_valid(ev));
}
{
CGAL::Exponent_vector ev(2,1);
assert(CGAL::is_valid(ev));
assert(ev[0] == 2);
assert(ev[1] == 1);
}
// trivariate
{
CGAL::Exponent_vector ev(0,0,-1);
assert(!CGAL::is_valid(ev));
}
{
CGAL::Exponent_vector ev(3,2,1);
assert(CGAL::is_valid(ev));
assert(ev[0] == 3);
assert(ev[1] == 2);
assert(ev[2] == 1);
}
// trivariate
{
CGAL::Exponent_vector ev(0,0,-1);
assert(!CGAL::is_valid(ev));
}
{
CGAL::Exponent_vector ev(3,2,1);
assert(CGAL::is_valid(ev));
assert(ev[0] == 3);
assert(ev[1] == 2);
assert(ev[2] == 1);
}
// four-variate
{
CGAL::Exponent_vector ev(0,0,0,-1);
assert(!CGAL::is_valid(ev));
}
{
CGAL::Exponent_vector ev(4,3,2,1);
assert(CGAL::is_valid(ev));
assert(ev[0] == 4);
assert(ev[1] == 3);
assert(ev[2] == 2);
assert(ev[3] == 1);
}
// four-variate
{
CGAL::Exponent_vector ev(0,0,0,-1);
assert(!CGAL::is_valid(ev));
}
{
CGAL::Exponent_vector ev(4,3,2,1);
assert(CGAL::is_valid(ev));
assert(ev[0] == 4);
assert(ev[1] == 3);
assert(ev[2] == 2);
assert(ev[3] == 1);
}
using std::swap; swap(ev1,ev2);
return 0;
return 0;
}