代码拉取完成,页面将自动刷新
#ifndef _VARARRAY_HPP_
#define _VARARRAY_HPP_
#include <array>
#include <cassert>
#include <cstring>
#include <initializer_list>
#include <string>
// #include <type_traits>
// FORTRAN 格式的索引是 列优先 如 a(2,3,4) 为2行3列4页
// 即一列有两个元素,一行有3个元素 页有四个(页)
// c 和 fortran 格式混搭了
// 除了Freconstruct 其余 c 均可用 只有先声明,后设置(用 Freconstruct
// 设置Fortran格式)
// c 格式为 2页 3行 四列 注意区分 行优先
// #define _FORTRAN_INDEX_
// #define _C_INDEX_
// options = 1 代表行优先 =0 为列优先
/**
* @brief 只是简单数组 不提供其他操作
*
* 不支持负的索引
*
* @tparam T 数据类型
* @tparam D 维度
* @tparam 1 1 代表行优先 C 模式 =0 为列优先 fortran模式 默认行优先
* 接口都一样,如果看上面 01 分类和 constexpr if 不顺眼可以分别实现
*/
template <typename T, int D, int options = 1>
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(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");
return dim[DD];
}
// 0 1 2 3
int Dim(int i) const
{
assert(i < D && -1 < i);
return dim[i];
}
// fortran 格式取值
T &operator()(index_t i) noexcept
{
static_assert(D == 1, "one index, one dimension");
assert(-1 < i && i < dim[0]);
return elem[i];
}
T &operator()(index_t i, index_t j) noexcept
{
static_assert(D == 2, "two index, two dimension");
assert(-1 < i && i < dim[0] && -1 < j && j < dim[1]);
if constexpr (options)
return elem[i * dim[1] + j];
else
return elem[j * dim[0] + i];
}
T &operator()(index_t i, index_t j, index_t k) 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]);
if constexpr (options)
return elem[(i * dim[1] + j) * dim[2] + k];
else
return elem[(k * dim[1] + j) * dim[0] + i];
}
T &operator()(index_t i, index_t j, index_t k, index_t m) 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]);
if constexpr (options)
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];
}
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;
// 跟复制函数是不同的,复制函数会清空原来的内存
inline void CopyValueFrom(const VarArray &src) noexcept;
inline void MoveValueFrom(VarArray &&src) noexcept;
inline VarArray &AssignValue(T val) noexcept;
inline VarArray &operator=(T d) noexcept;
inline VarArray &operator*=(T fac) noexcept;
inline VarArray &operator/=(T fac) noexcept;
inline VarArray &operator+=(T fac) noexcept;
inline VarArray &operator-=(T 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开始
std::array<int, D> dim{};
index_t sz{};
T *elem{};
// 添加引用指针试一试
mutable bool owner{true};
void copy_from(const VarArray &src);
void move_from(VarArray &src);
};
template <typename T, int D, int options>
void VarArray<T, D, options>::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, int options>
void VarArray<T, D, options>::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, int options>
VarArray<T, D, options>::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, int options>
VarArray<T, D, options>::VarArray(const VarArray &src)
{
copy_from(src);
}
// 移动构造函数
template <typename T, int D, int options>
VarArray<T, D, options>::VarArray(VarArray &&src)
{
move_from(src);
}
template <typename T, int D, int options>
VarArray<T, D, options>::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];
}
// 赋值运算符
template <typename T, int D, int options>
VarArray<T, D, options> &VarArray<T, D, options>::
operator=(const VarArray &src)
{
if (this == &src)
return *this;
delete[] elem;
copy_from(src);
return *this;
}
// 移动赋值运算符
template <typename T, int D, int options>
VarArray<T, D, options> &VarArray<T, D, options>::operator=(VarArray &&src)
{
if (this == &src)
return src;
delete[] elem;
move_from(src);
}
template <typename T, int D, int options>
const T &VarArray<T, D, options>::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, int options>
const T &VarArray<T, D, options>::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]);
if constexpr (options)
return elem[i * dim[1] + j];
else
return elem[j * dim[0] + i];
}
template <typename T, int D, int options>
const T &VarArray<T, D, options>::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]);
if constexpr (options)
return elem[(i * dim[1] + j) * dim[2] + k];
else
return elem[(k * dim[1] + j) * dim[0] + i];
}
template <typename T, int D, int options>
const T &VarArray<T, D, options>::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]);
if constexpr (options)
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];
}
template <typename T, int D, int options>
bool VarArray<T, D, options>::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, int options>
bool VarArray<T, D, options>::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, int options>
bool VarArray<T, D, options>::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, int options>
bool VarArray<T, D, options>::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, int options>
void VarArray<T, D, options>::CopyValueFrom(const VarArray &src) noexcept
{
if (this == &src)
return;
assert(dim == src.dim);
memcpy(elem, src.elem, sizeof(T) * sz);
}
template <typename T, int D, int options>
void VarArray<T, D, options>::MoveValueFrom(VarArray &&src) noexcept
{
if (this == &src)
return;
assert(dim == src.dim);
delete[] elem;
elem = src.elem;
sz = src.dim[0] = 0;
}
template <typename T, int D, int options>
VarArray<T, D, options> &VarArray<T, D, options>::
operator*=(T fac) noexcept
{
for (index_t i = 0; i < sz; ++i)
elem[i] *= fac;
return *this;
}
template <typename T, int D, int options>
VarArray<T, D, options> &VarArray<T, D, options>::
operator/=(T fac) noexcept
{
for (index_t i = 0; i < sz; ++i)
elem[i] /= fac;
return *this;
}
template <typename T, int D, int options>
VarArray<T, D, options> &VarArray<T, D, options>::
operator+=(T fac) noexcept
{
for (index_t i = 0; i < sz; ++i)
elem[i] += fac;
return *this;
}
template <typename T, int D, int options>
VarArray<T, D, options> &VarArray<T, D, options>::
operator-=(T fac) noexcept
{
for (index_t i = 0; i < sz; ++i)
elem[i] -= fac;
return *this;
}
template <typename T, int D, int options>
VarArray<T, D, options> &VarArray<T, D, options>::AssignValue(T val) noexcept
{
for (index_t i = 0; i < sz; ++i)
elem[i] = val;
return *this;
}
template <typename T, int D, int options>
VarArray<T, D, options> &VarArray<T, D, options>::operator=(T d) noexcept
{
for (index_t i = 0; i < sz; ++i)
elem[i] = d;
return *this;
}
#endif
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。