1 Star 0 Fork 0

xjDing/include

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
vararray_old.hpp 12.67 KB
一键复制 编辑 原始数据 按行查看 历史
xjDing 提交于 2019-05-06 20:55 +08:00 . add all files
#ifndef _VARARRAY_HPP_
#define _VARARRAY_HPP_
#include <initializer_list>
#include <cassert>
#include <cstring>
#include <array>
#include <type_traits>
#include <string>
// FORTRAN 格式的索引是 列优先 如 a(2,3,4) 为2行3列4页
// 即一列有两个元素,一行有3个元素 页有四个(页)
// c 和 fortran 格式混搭了
// 除了Freconstruct 其余 c 均可用 只有先声明,后设置(用 Freconstruct 设置Fortran格式)
// c 格式为 2页 3行 四列 注意区分 行优先
// #define _FORTRAN_INDEX_
#define _C_INDEX_
/**
* @brief
* 表达式模板有待添加
* @tparam T
* @tparam D
*/
template <typename T, int D>
class VarArray
{
public:
typedef int index_t;
typedef T *iter;
typedef const T *const_iter;
typedef T value_type;
typedef T &reference;
typedef const T &const_reference;
// using iter = T *;
// using const_iter = const T *;
// using value_type = T;
// 构造函数和拷贝函数
VarArray() = default;
VarArray(index_t i, index_t j = 0,
index_t k = 0, index_t m = 0);
// VarArray(const std::string str1, const std::string str2 = "",
// const std::string str3 = "", const std::string str4 = "");
VarArray(std::initializer_list<index_t> dimList);
VarArray(const VarArray &src);
VarArray(VarArray &&src);
VarArray &operator=(const VarArray &src);
VarArray &operator=(VarArray &&src);
~VarArray() { delete[] elem; }
// 获取相应维度, 最后一个维度变化最快 c 模式 0 1 2 3
template <int DD>
int Dim() const
{
static_assert(DD < D, "exceed the dimension you have defined\n");
#ifdef _C_INDEX_
return dim[DD];
#endif
#ifdef _FORTRAN_INDEX_
return dim[DD * 2 + 1];
#endif
}
// 0 1 2 3
int Dim(int i) const
{
assert(i < D && -1 < i);
#ifdef _C_INDEX_
return dim[i];
#endif
#ifdef _FORTRAN_INDEX_
return dim[i * 2 + 1];
#endif
}
// fortran 格式取值
T &operator()(index_t i) noexcept
{
static_assert(D == 1, "one index, one dimension");
#ifdef _C_INDEX_
assert(-1 < i && i < dim[0]);
return elem[i];
#endif
#ifdef _FORTRAN_INDEX_
assert(dim[0] <= i && i <= (dim[1] + dim[0] - 1));
return elem[i - dim[0]];
#endif
}
T &operator()(index_t i, index_t j) noexcept
{
static_assert(D == 2, "two index, two dimension");
#ifdef _C_INDEX_
assert(-1 < i && i < dim[0] && -1 < j && j < dim[1]);
return elem[i * dim[1] + j];
#else
assert(dim[0] <= i && i <= (dim[1] + dim[0] - 1) &&
dim[2] <= j && j <= (dim[3] + dim[2] - 1));
return elem[(j - dim[2]) * dim[1] + i - dim[0]];
#endif
}
T &operator()(index_t i, index_t j, index_t k) noexcept
{
static_assert(D == 3, "three index, three dimension");
#ifdef _C_INDEX_
assert(-1 < i && i < dim[0] && -1 < j && j < dim[1] &&
-1 < k && k < dim[2]);
return elem[(i * dim[1] + j) * dim[2] + k];
#else
assert(dim[0] <= i && i <= (dim[1] + dim[0] - 1) &&
dim[2] <= j && j <= (dim[3] + dim[2] - 1) &&
dim[4] <= k && k <= (dim[5] + dim[4] - 1));
return elem[((k - dim[4]) * dim[3] + j - dim[2]) * dim[1] + i - dim[0]];
// return elem[(k * dim[1] + j) * dim[0] + i];
#endif
}
T &operator()(index_t i, index_t j, index_t k, index_t m) noexcept
{
static_assert(D == 4, "four index, four dimension");
#ifdef _C_INDEX_
assert(-1 < i && i < dim[0] && -1 < j && j < dim[1] &&
-1 < k && k < dim[2] && -1 < m && m < dim[3]);
return elem[((i * dim[1] + j) * dim[2] + k) * dim[3] + m];
#else
assert(dim[0] <= i && i <= (dim[1] + dim[0] - 1) &&
dim[2] <= j && j <= (dim[3] + dim[2] - 1) &&
dim[4] <= k && k <= (dim[5] + dim[4] - 1) &&
dim[6] <= m && m <= (dim[7] + dim[6] - 1));
return elem[(((m - dim[6]) * dim[5] + k - dim[4]) * dim[3] + j - dim[2]) * dim[1] + i - dim[0]];
#endif
}
inline const_reference operator()(index_t i)
const noexcept;
inline const_reference operator()(index_t i, index_t j)
const noexcept;
inline const_reference operator()(index_t i, index_t j,
index_t k)
const noexcept;
inline const_reference operator()(index_t i, index_t j,
index_t k, index_t m)
const noexcept;
// 重新分配内存和各维度大小 这个函数使用不频繁,可以简写
inline bool ReConstruct(int i) noexcept;
inline bool ReConstruct(int i, int j) noexcept;
inline bool ReConstruct(int i, int j, int k) noexcept;
inline bool ReConstruct(int i, int j, int k, int m) noexcept;
#ifdef _FORTRAN_INDEX_
// 不嫌麻烦的话可以写类似上面的四个
bool FReConstruct(int i1, int i2,
int j1 = 0, int j2 = 0,
int k1 = 0, int k2 = 0,
int m1 = 0, int m2 = 0);
#endif
// 跟复制函数是不同的,复制函数会清空原来的内存
inline void CopyValueFrom(const VarArray &src) noexcept;
inline void MoveValueFrom(VarArray &&src) noexcept;
inline VarArray &AssignValue(T val) noexcept;
inline VarArray &operator=(double d) noexcept;
inline VarArray &operator*=(double fac) noexcept;
inline VarArray &operator/=(double fac) noexcept;
inline VarArray &operator+=(double fac) noexcept;
inline VarArray &operator-=(double fac) noexcept;
iter begin() noexcept { return elem; }
const_iter begin() const noexcept { return elem; }
iter end() noexcept { return elem + sz; }
const_iter end() const noexcept { return elem + sz; }
index_t size() const noexcept { return sz; }
iter data() noexcept { return elem; }
const_iter data() const noexcept { return elem; }
private:
// 默认从0开始
#ifdef _FORTRAN_INDEX_
std::array<int, 2 * D> dim{};
#else
std::array<int, D> dim{};
#endif
T *elem{};
index_t sz{};
void copy_from(const VarArray &src);
void move_from(VarArray &src);
};
template <typename T, int D>
void VarArray<T, D>::copy_from(const VarArray &src)
{
dim = src.dim;
sz = src.sz;
elem = new T[sz];
assert(elem);
memcpy(elem, src.elem, sizeof(T) * sz);
}
template <typename T, int D>
void VarArray<T, D>::move_from(VarArray &src)
{
dim = src.dim;
sz = src.sz;
elem = src.elem;
src.sz = 0;
src.elem = nullptr;
src.dim[0] = 0;
}
/**
* @brief Construct a new Var Array< T, D>:: Var Array object
* 唯一的可以指定维度初始化
* @tparam T
* @tparam D
* @param dimList
*/
template <typename T, int D>
VarArray<T, D>::VarArray(std::initializer_list<index_t> dimList)
{
index_t size = dimList.size();
assert(D == size);
const index_t *beg = dimList.begin();
index_t tmp{1};
for (index_t i = 0; i < size; ++i)
{
dim[i] = *beg++;
tmp *= dim[i];
}
sz = tmp;
elem = new T[sz];
assert(elem);
}
// 拷贝构造函数
template <typename T, int D>
VarArray<T, D>::VarArray(const VarArray &src)
{
copy_from(src);
}
// 移动构造函数
template <typename T, int D>
VarArray<T, D>::VarArray(VarArray &&src)
{
move_from(src);
}
template <typename T, int D>
VarArray<T, D>::VarArray(index_t i, index_t j,
index_t k, index_t m)
{
sz = 1;
// 这样写的话判断条件没有那么严格了
switch (D)
{
case 4:
assert(m > 0);
dim[3] = m;
sz = sz * m;
case 3:
assert(k > 0);
dim[2] = k;
sz = sz * k;
case 2:
assert(j > 0);
dim[1] = j;
sz = sz * j;
case 1:
dim[0] = i;
sz = sz * i;
break;
default:
assert(D < 5 && 0 < D);
break;
}
elem = new T[sz];
}
#ifdef _FORTRAN_INDEX_
template <typename T, int D>
bool VarArray<T, D>::FReConstruct(int i1, int i2, int j1, int j2,
int k1, int k2, int m1, int m2)
{
assert(i1 <= i2 && j1 <= j2 && k1 <= k2 && m1 <= m2);
switch (D)
{
// 起点和跨距
case 4:
dim[6] = m1;
dim[7] = m2 - m1 + 1;
case 3:
dim[4] = k1;
dim[5] = k2 - k1 + 1;
case 2:
dim[2] = j1;
dim[3] = j2 - j1 + 1;
case 1:
dim[0] = i1;
dim[1] = i2 - i1 + 1;
break;
// 下面为错误的情况
default:
assert(0 < D && D < 5);
break;
}
sz = dim[1] * dim[3] * dim[5] * dim[7];
return elem = new T[sz];
}
#endif
// 赋值运算符
template <typename T, int D>
VarArray<T, D> &VarArray<T, D>::operator=(const VarArray &src)
{
if (this == &src)
return src;
delete[] elem;
copy_from(src);
return *this;
}
// 移动赋值运算符
template <typename T, int D>
VarArray<T, D> &VarArray<T, D>::operator=(VarArray &&src)
{
if (this == &src)
return src;
delete[] elem;
move_from(src);
}
template <typename T, int D>
const T &VarArray<T, D>::operator()(index_t i) const noexcept
{
static_assert(D == 1, "one index, one dimension");
assert(-1 < i && i < dim[0]);
return elem[i];
}
template <typename T, int D>
const T &VarArray<T, D>::operator()(index_t i, index_t j)
const noexcept
{
static_assert(D == 2, "two index, two dimension");
assert(-1 < i && i < dim[0] && -1 < j && j < dim[1]);
#ifdef _C_INDEX_
return elem[i * dim[1] + j];
#else
return elem[j * dim[0] + i];
#endif
}
template <typename T, int D>
const T &VarArray<T, D>::operator()(index_t i, index_t j,
index_t k) const noexcept
{
static_assert(D == 3, "three index, three dimension");
assert(-1 < i && i < dim[0] && -1 < j && j < dim[1] &&
-1 < k && k < dim[2]);
#ifdef _C_INDEX_
return elem[(i * dim[1] + j) * dim[2] + k];
#else
return elem[(k * dim[1] + j) * dim[0] + i];
#endif
}
template <typename T, int D>
const T &VarArray<T, D>::operator()(
index_t i, index_t j, index_t k, index_t m) const noexcept
{
static_assert(D == 4, "four index, four dimension");
assert(-1 < i && i < dim[0] && -1 < j && j < dim[1] &&
-1 < k && k < dim[2] && -1 < m && m < dim[3]);
#ifdef _C_INDEX_
return elem[((i * dim[1] + j) * dim[2] + k) * dim[3] + m];
#else
return elem[((m * dim[2] + k) * dim[1] + j) * dim[0] + i];
#endif
}
template <typename T, int D>
bool VarArray<T, D>::ReConstruct(int i) noexcept
{
static_assert(D == 1, "not match the dimension");
delete[] elem;
sz = dim[0] = i;
return elem = new T[i];
}
template <typename T, int D>
bool VarArray<T, D>::ReConstruct(int i, int j) noexcept
{
static_assert(D == 2, "not match the dimension");
delete[] elem;
dim[0] = i;
dim[1] = j;
sz = i * j;
return elem = new T[sz];
}
template <typename T, int D>
bool VarArray<T, D>::ReConstruct(int i, int j, int k) noexcept
{
static_assert(D == 3, "not match the dimension");
delete[] elem;
dim[0] = i;
dim[1] = j;
dim[2] = k;
sz = i * j * k;
return elem = new T[sz];
}
template <typename T, int D>
bool VarArray<T, D>::ReConstruct(int i, int j, int k, int m) noexcept
{
static_assert(D == 4, "not match the dimension");
delete[] elem;
dim[0] = i;
dim[1] = j;
dim[2] = k;
dim[3] = m;
sz = i * j * k * m;
return elem = new T[sz];
}
template <typename T, int D>
void VarArray<T, D>::CopyValueFrom(const VarArray &src) noexcept
{
assert(dim == src.dim);
memcpy(elem, src.elem, sizeof(T) * sz);
}
template <typename T, int D>
void VarArray<T, D>::MoveValueFrom(VarArray &&src) noexcept
{
assert(dim == src.dim);
delete[] elem;
elem = src.elem;
sz = src.dim[0] = 0;
}
template <typename T, int D>
VarArray<T, D> &VarArray<T, D>::operator*=(double fac) noexcept
{
for (index_t i = 0; i < sz; ++i)
elem[i] *= fac;
return *this;
}
template <typename T, int D>
VarArray<T, D> &VarArray<T, D>::operator/=(double fac) noexcept
{
for (index_t i = 0; i < sz; ++i)
elem[i] /= fac;
return *this;
}
template <typename T, int D>
VarArray<T, D> &VarArray<T, D>::operator+=(double fac) noexcept
{
for (index_t i = 0; i < sz; ++i)
elem[i] += fac;
return *this;
}
template <typename T, int D>
VarArray<T, D> &VarArray<T, D>::operator-=(double fac) noexcept
{
for (index_t i = 0; i < sz; ++i)
elem[i] -= fac;
return *this;
}
template <typename T, int D>
VarArray<T, D> &VarArray<T, D>::AssignValue(T val) noexcept
{
for (index_t i = 0; i < sz; ++i)
elem[i] = val;
return *this;
}
template <typename T, int D>
VarArray<T, D> &VarArray<T, D>::operator=(double d) noexcept
{
for (index_t i = 0; i < sz; ++i)
elem[i] = d;
return *this;
}
#endif
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/dingxuejun/include.git
git@gitee.com:dingxuejun/include.git
dingxuejun
include
include
master

搜索帮助