#ifndef gra_IdentityPoints_H__
#define gra_IdentityPoints_H__
#include "../Self.h"
#include "../math/Vector.h"
#include "../oo/ObjBase.h"
#include <map>
#include <set>
#include <cstdlib>
namespace meow {
/*!
* @brief 把一個 \c std::map<ID,Vector<Scalar> > 包起來
*
* @author cat_leopard
*/
template<class ID, class Scalar>
class IdentityPoints: public ObjBase {
public:
typedef typename std::map<ID, Vector<Scalar> > IdentityPointsMap;
typedef typename IdentityPointsMap:: iterator IdentityPointsMapIter;
typedef typename IdentityPointsMap::const_iterator IdentityPointsMapIterK;
private:
struct Myself {
IdentityPointsMap points_;
size_t dimension_;
Myself(): dimension_(1) {
}
Myself(Myself const& m): points_(m.points_), dimension_(m.dimension_) {
}
~Myself() {
}
};
Self<Myself> const self;
public:
/*!
* @brief constructor
*/
IdentityPoints(): self() {
}
/*!
* @brief constructor, 並且複製資料
*/
IdentityPoints(IdentityPoints const& b):
self(b.self, Self<Myself>::COPY_FROM) {
}
/*!
* @brief destructor
*/
~IdentityPoints() {
}
/*!
* @brief 複製資料
*/
IdentityPoints& copyFrom(IdentityPoints const& b) {
self().copyFrom(b.self);
return *this;
}
/*!
* @brief 參照
*/
IdentityPoints& referenceFrom(IdentityPoints const& b) {
self().referenceFrom(b.self);
return *this;
}
/*!
* @brief 清除一切identity points
*/
void clear() {
self()->points_.clear();
}
/*!
* @brief 回傳有幾個identity points
*/
size_t size() const {
return self->points_.size();
}
/*!
* @brief 回傳是否沒有identity points
*/
bool empty() const {
return (size() == 0u);
}
/*!
* @brief 檢查某id是否有使用
*/
bool exist(ID const& id) const {
return (self->points_.find(id) != self->points_.end());
}
/*!
* @brief 回傳dimension
*/
size_t dimension() const {
return self->dimension_;
}
/*!
* @brief 設定dimension, 並且清空資料
*/
size_t dimension(size_t dim) {
self()->dimension_ = dim;
clear();
return dimension();
}
/*!
* @brief 設定dimension, 並且針對每個identity point指定重設dimension
*/
size_t dimension(size_t dim, Scalar const& init_value) {
self()->dimension_ = dim;
for (IdentityPointsMapIter
it = self()->points_.begin(); it != self()->points_.end(); ++it) {
it.second.dimension(dim, init_value);
}
return dimension();
}
/*!
* @brief 取得所有identity points
*/
IdentityPointsMap const& points() const {
return self()->points_;
}
/*!
* @brief 設定所有identity points
*/
IdentityPointsMap const& points(IdentityPointsMap const& points) {
clear();
return pointsAdd(points);
}
/*!
* @brief 加入identity Points
*/
IdentityPointsMap const& pointsAdd(IdentityPointsMap const& points) {
for (IdentityPointsMapIterK it = points.begin(); it != points.end(); ++it) {
pointAdd(it.first, it.second);
}
return points();
}
/*!
* @brief 移除identity Points
*/
IdentityPointsMap const& pointsDel(std::set<ID> const& ids) {
for (typename std::set<ID>::const_iterator
it = ids.begin(); it != ids.end(); ++it) {
pointDel(*it);
}
return points();
}
/*!
* @brief 取得一個identity point
*/
Vector<Scalar> point(ID const& id) const {
return (exist(id) ? self->points_.find(id)->second : Vector<Scalar>());
}
/*!
* @brief 修改一個identity point
*/
Vector<Scalar> point(ID const& id, Vector<Scalar> const& b) {
if (b.dimension() == self->dimension_ && exist(id)) {
self()->points_[id].copyFrom(b);
}
return point(id);
}
/*!
* @brief 新增一個identity point
*/
Vector<Scalar> pointAdd(ID const& id, Vector<Scalar> const& b) {
if (b.dimension() == self->dimension_ && !exist(id)) {
self()->points_[id].copyFrom(b);
}
return point(id);
}
/*!
* @brief 刪除一個identity point
*/
void pointDel(ID const& id) {
self()->points_.erase(id);
}
/*!
* @brief 取得一個identity point, non-constant reference
*/
Vector<Scalar>& pointGet(ID const& id) {
return self()->points_[id];
}
/*!
* @brief same as \c copyFrom(b)
*/
IdentityPoints& operator=(IdentityPoints const& b) {
return copyFrom(b);
}
/*! @brief 將資料寫入檔案
*
* @note 未完成
*/
bool write(FILE* f, bool bin, unsigned int fg) const {
if (bin) {
long dim, ct;
if (fwrite(&(dim = dimension()), sizeof(dim), 1, f) < 1) return false;
if (fwrite(&(ct = size()), sizeof(ct), 1, f) < 1) return false;
for (IdentityPointsMapIterK
it = points().begin(), ed = points().end(); it != ed; ++it) {
double tmp;
if (fwrite(&(tmp = it->first), sizeof(tmp), 1, f) < 1) return false;
for (long i = 0; i < dim; ++i) {
if (fwrite(&(tmp = it->second(i)), sizeof(tmp), 1, f) < 1)
return false;
}
}
}
else {
if (fprintf(f, "%ld %lu\n", dimension(), size()) < 1) return false;
for (IdentityPointsMapIterK
it = points().begin(), ed = points().end(); it != ed; ++it) {
if (fprintf(f, "%f ", (double)it->first) < 1) return false;
for (long i = 0, I = dimension(); i < I; ++i) {
if (fprintf(f, "%f ", (double)it->second(i)) < 1) return false;
}
fprintf(f, "\n");
}
}
return true;
}
/*! @brief 將資料讀入
*
* @note 未完成
*/
bool read(FILE* f, bool bin, unsigned int fg) {
long dim, ct;
if (bin) {
if (fread(&dim, sizeof(dim), 1, f) < 1) return false;
dimension(dim);
if (fread(&ct, sizeof(ct), 1, f) < 1) return false;
double id, tt;
Vector<Scalar> tmp(dim, 0);
for (int i = 0; i < ct; ++i) {
if (fread(&id, sizeof(id), 1, f) < 1) return false;
for (size_t j = 0, J = dim; j < J; ++j) {
if (fread(&tt, sizeof(tt), 1, f) < 1) return false;
tmp.scalar(j, tt);
}
pointAdd((ID)id, tmp);
}
}
else {
if (fscanf(f, "%ld %ld", &dim, &ct) < 2) return false;
dimension(dim);
double id, tt;
Vector<Scalar> tmp(dim, 0);
for (int i = 0; i < ct; ++i) {
if (fscanf(f, "%lf", &id) < 1) return false;
for (int j = 0, J = dim; j < J; ++j) {
if (fscanf(f, "%lf", &tt) < 1) return false;
tmp.scalar(j, tt);
}
pointAdd((ID)id, tmp);
}
}
return true;
}
/*! @brief new一個自己
*
* @return 一個new出來的Bitmap<Pixel>
*/
ObjBase* create() const {
return new IdentityPoints();
}
/*! @brief 複製資料
*
* 輸入型別是 \c ObjBase \c const*
* 這裡假設實體其實是 \c Bitmap.
* 事實上這個method就只是幫忙轉型然後呼叫原本的\c copyFrom
*
* @param [in] b 資料來源
* @return this
*/
ObjBase* copyFrom(ObjBase const* b) {
return &(copyFrom(*(IdentityPoints*)b));
}
/*! @brief 回傳class的type
*
* @return \c char \c const\c * 形式的typename
*/
char const* ctype() const {
return typeid(*this).name();
}
/*! @brief 回傳class的type
*
* @return \c std::string 形式的typename
*/
std::string type() const {
return std::string(ctype());
}
};
} // meow
#endif // gra_IdentityPoints_H__