/*
* vmg - a versatile multigrid solver
* Copyright (C) 2012 Institute for Numerical Simulation, University of Bonn
*
* vmg is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* vmg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/**
* @file index.hpp
* @author Julian Iseringhausen
* @date Mon Apr 18 12:19:49 2011
*
* @brief Header file for the class VMG::Index.
*
*/
#ifndef INDEX_HPP_
#define INDEX_HPP_
#include
#include
#include
#include
#include
namespace VMG
{
class Vector;
class Index
{
public:
Index(const Index& rhs);
Index(const Vector& vec);
Index(int x, int y, int z) {i[0]=x;i[1]=y;i[2]=z;}
Index(int val) {i[0]=val;i[1]=val;i[2]=val;}
Index(int* arr) {i[0]=arr[0];i[1]=arr[1];i[2]=arr[2];}
Index() {i[0]=0;i[1]=0;i[2]=0;}
int& operator[](const int& index) {return i[index];}
const int& operator[](const int& index) const {return i[index];}
int& X() {return i[0];}
int& Y() {return i[1];}
int& Z() {return i[2];}
const int& X() const {return i[0];}
const int& Y() const {return i[1];}
const int& Z() const {return i[2];}
Index Abs() {return Index(abs(i[0]), abs(i[1]), abs(i[2]));}
int Max() const {return std::max(std::max(i[0],i[1]),i[2]);}
int Min() const {return std::min(std::min(i[0],i[1]),i[2]);}
int Product() const {return i[0]*i[1]*i[2];}
int Sum() const {return i[0]+i[1]+i[2];}
bool IsInBounds(const Index& begin, const Index& end) const
{
return i[0] >= begin[0] && i[0] < end[0] &&
i[1] >= begin[1] && i[1] < end[1] &&
i[2] >= begin[2] && i[2] < end[2];
}
bool IsComponentwiseLess(const Index& other) const
{
return this->i[0] < other.i[0]
&& this->i[1] < other.i[1]
&& this->i[2] < other.i[2];
}
bool IsComponentwiseLessOrEqual(const Index& other) const
{
return this->i[0] <= other.i[0]
&& this->i[1] <= other.i[1]
&& this->i[2] <= other.i[2];
}
bool IsComponentwiseGreater(const Index& other) const
{
return this->i[0] > other.i[0]
&& this->i[1] > other.i[1]
&& this->i[2] > other.i[2];
}
bool IsComponentwiseGreaterOrEqual(const Index& other) const
{
return this->i[0] >= other.i[0]
&& this->i[1] >= other.i[1]
&& this->i[2] >= other.i[2];
}
Index MaxComponentwise(const Index& rhs) const
{
return Index(std::max(i[0], rhs.i[0]), std::max(i[1], rhs.i[1]), std::max(i[2], rhs.i[2]));
}
Index MinComponentwise(const Index& rhs) const
{
return Index(std::min(i[0], rhs.i[0]), std::min(i[1], rhs.i[1]), std::min(i[2], rhs.i[2]));
}
Index Clamp(const Index& lower_bound, const Index& upper_bound) const
{
Index index(*this);
for (int j=0; j<3; ++j) {
index.i[j] = std::max(index.i[j], lower_bound[j]);
index.i[j] = std::min(index.i[j], upper_bound[j]);
}
return index;
}
int* vec() {return i;}
const int* vec() const {return i;}
Index& operator=(const Index& rhs)
{
i[0] = rhs.X();
i[1] = rhs.Y();
i[2] = rhs.Z();
return *this;
}
Index& operator=(const int& rhs)
{
i[0] = rhs;
i[1] = rhs;
i[2] = rhs;
return *this;
}
bool operator==(const Index& other) const
{
return (i[0]==other.X() && i[1]==other.Y() && i[2]==other.Z());
}
bool operator<(const Index& other) const
{
for (int j=0; j<3; ++j) {
if (this->i[j] < other.i[j]) return true;
if (this->i[j] != other.i[j]) return false;
}
return false;
}
bool operator!=(const Index& other) const
{
return !(*this == other);
}
Index& operator+=(const Index& rhs)
{
i[0] += rhs.X();
i[1] += rhs.Y();
i[2] += rhs.Z();
return *this;
}
Index& operator-=(const Index& rhs)
{
i[0] -= rhs.X();
i[1] -= rhs.Y();
i[2] -= rhs.Z();
return *this;
}
Index& operator*=(const Index& rhs)
{
i[0] *= rhs.X();
i[1] *= rhs.Y();
i[2] *= rhs.Z();
return *this;
}
Index& operator/=(const Index& rhs)
{
i[0] /= rhs.X();
i[1] /= rhs.Y();
i[2] /= rhs.Z();
return *this;
}
Index& operator%=(const Index& rhs)
{
i[0] %= rhs.X();
i[1] %= rhs.Y();
i[2] %= rhs.Z();
return *this;
}
Index& operator+=(const int& rhs)
{
i[0] += rhs;
i[1] += rhs;
i[2] += rhs;
return *this;
}
Index& operator-=(const int& rhs)
{
i[0] -= rhs;
i[1] -= rhs;
i[2] -= rhs;
return *this;
}
Index& operator*=(const int& rhs)
{
i[0] *= rhs;
i[1] *= rhs;
i[2] *= rhs;
return *this;
}
Index& operator/=(const int& rhs)
{
i[0] /= rhs;
i[1] /= rhs;
i[2] /= rhs;
return *this;
}
Index& operator%=(const int& rhs)
{
i[0] %= rhs;
i[1] %= rhs;
i[2] %= rhs;
return *this;
}
Index operator+(const Index& rhs) const
{
return Index(*this) += rhs;
}
Index operator-(const Index& rhs) const
{
return Index(*this) -= rhs;
}
Index operator*(const Index& rhs) const
{
return Index(*this) *= rhs;
}
Index operator/(const Index& rhs) const
{
return Index(*this) /= rhs;
}
Index operator%(const Index& rhs) const
{
return Index(*this) %= rhs;
}
Index operator+(const int& rhs) const
{
return Index(*this) += rhs;
}
Index operator-(const int& rhs) const
{
return Index(*this) -= rhs;
}
Index operator*(const int& rhs) const
{
return Index(*this) *= rhs;
}
Index operator/(const int& rhs) const
{
return Index(*this) /= rhs;
}
Index operator%(const int& rhs) const
{
return Index(*this) %= rhs;
}
Vector operator+(const Vector& rhs) const;
Vector operator-(const Vector& rhs) const;
Vector operator*(const Vector& rhs) const;
Vector operator/(const Vector& rhs) const;
Vector operator+(const vmg_float& rhs) const;
Vector operator-(const vmg_float& rhs) const;
Vector operator*(const vmg_float& rhs) const;
Vector operator/(const vmg_float& rhs) const;
private:
int i[3];
};
inline Index operator+(const int& lhs, const Index& rhs)
{
return Index(lhs) += rhs;
}
inline Index operator-(const int& lhs, const Index& rhs)
{
return Index(lhs) -= rhs;
}
inline Index operator*(const int& lhs, const Index& rhs)
{
return Index(lhs) *= rhs;
}
inline Index operator/(const int& lhs, const Index& rhs)
{
return Index(lhs) /= rhs;
}
inline Index operator%(const int& lhs, const Index& rhs)
{
return Index(lhs) %= rhs;
}
const Index Max(const Index& index1, const Index& index2);
std::ostream& operator<<(std::ostream& out, const Index& index);
}
#endif /* INDEX_HPP_ */