代码拉取完成,页面将自动刷新
#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 不顺眼可以分别实现
*/
////////////////////////////////////////////////////////////////////////////////////构造函数的继承
// namespace VarArray_new
// {
constexpr int FORTRAN_ARRAY{0};
constexpr int C_ARRAY{1};
template <typename T, int D> class VarArrayBase;
/**
* @brief 主模板仅仅是有声明和检查的作用,通过特例化实现
*
* @tparam T
* @tparam D 数组维度
* @tparam option 区分行优先还是列优先
*/
template <typename T, int D, int option = FORTRAN_ARRAY> class VarArray {
static_assert(option == FORTRAN_ARRAY || option == C_ARRAY, "option:\n \
0 or FORTRAN_ARRAY fortran type array \n \
1 or C_ARRAY for c type array");
};
/**
* @brief fortran 格式的数组取值
*
* @tparam T
* @tparam D
*/
template <typename T, int D>
class VarArray<T, D, FORTRAN_ARRAY> : public VarArrayBase<T, D> {
public:
using base = VarArrayBase<T, D>;
using index_t = typename base::index_t;
// 继承构造函数
using VarArrayBase<T, D>::VarArrayBase;
T &operator()(index_t i, index_t j) noexcept {
static_assert(D == 2, "two index, two dimension");
assert(-1 < i && i < base::dim[0] && -1 < j && j < base::dim[1]);
return base::elem[j * base::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 < base::dim[0] && -1 < j && j < base::dim[1] && -1 < k &&
k < base::dim[2]);
return base::elem[(k * base::dim[1] + j) * base::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 < base::dim[0] && -1 < j && j < base::dim[1] && -1 < k &&
k < base::dim[2] && -1 < m && m < base::dim[3]);
return base::elem[((m * base::dim[2] + k) * base::dim[1] + j) *
base::dim[0] +
i];
}
const T &operator()(index_t i, index_t j) const noexcept {
static_assert(D == 2, "two index, two dimension");
assert(-1 < i && i < base::dim[0] && -1 < j && j < base::dim[1]);
return base::elem[j * base::dim[0] + i];
}
const T &operator()(index_t i, index_t j, index_t k) const noexcept {
static_assert(D == 3, "three index, three dimension");
assert(-1 < i && i < base::dim[0] && -1 < j && j < base::dim[1] && -1 < k &&
k < base::dim[2]);
return base::elem[(k * base::dim[1] + j) * base::dim[0] + i];
}
const T &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 < base::dim[0] && -1 < j && j < base::dim[1] && -1 < k &&
k < base::dim[2] && -1 < m && m < base::dim[3]);
return base::elem[((m * base::dim[2] + k) * base::dim[1] + j) *
base::dim[0] +
i];
}
VarArray &AssignValue(T val) noexcept {
base::AssignValue(val);
return *this;
}
VarArray &operator=(T d) noexcept {
base::operator=(d);
return *this;
}
VarArray &operator*=(T fac) noexcept {
base::operator*=(fac);
return *this;
}
VarArray &operator/=(T fac) noexcept {
base::operator/=(fac);
return *this;
}
VarArray &operator+=(T fac) noexcept {
base::operator+=(fac);
return *this;
}
VarArray &operator-=(T fac) noexcept {
base::operator-=(fac);
return *this;
}
};
template <typename T, int D>
class VarArray<T, D, C_ARRAY> : public VarArrayBase<T, D> {
public:
using base = VarArrayBase<T, D>;
using VarArrayBase<T, D>::VarArrayBase;
using index_t = typename base::index_t;
T &operator()(index_t i, index_t j) noexcept {
static_assert(D == 2, "two index, two dimension");
assert(-1 < i && i < base::dim[0] && -1 < j && j < base::dim[1]);
return base::elem[i * base::dim[1] + j];
}
T &operator()(index_t i, index_t j, index_t k) noexcept {
static_assert(D == 3, "three index, three dimension");
assert(-1 < i && i < base::dim[0] && -1 < j && j < base::dim[1] && -1 < k &&
k < base::dim[2]);
return base::elem[(i * base::dim[1] + j) * base::dim[2] + k];
}
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 < base::dim[0] && -1 < j && j < base::dim[1] && -1 < k &&
k < base::dim[2] && -1 < m && m < base::dim[3]);
return base::elem[((i * base::dim[1] + j) * base::dim[2] + k) *
base::dim[3] +
m];
}
const T &operator()(index_t i, index_t j) const noexcept {
static_assert(D == 2, "two index, two dimension");
assert(-1 < i && i < base::dim[0] && -1 < j && j < base::dim[1]);
return base::elem[i * base::dim[1] + j];
}
const T &operator()(index_t i, index_t j, index_t k) const noexcept {
static_assert(D == 3, "three index, three dimension");
assert(-1 < i && i < base::dim[0] && -1 < j && j < base::dim[1] && -1 < k &&
k < base::dim[2]);
return base::elem[(i * base::dim[1] + j) * base::dim[2] + k];
}
const T &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 < base::dim[0] && -1 < j && j < base::dim[1] && -1 < k &&
k < base::dim[2] && -1 < m && m < base::dim[3]);
return base::elem[((i * base::dim[1] + j) * base::dim[2] + k) *
base::dim[3] +
m];
}
VarArray &AssignValue(T val) noexcept {
base::AssignValue(val);
return *this;
}
VarArray &operator=(T d) noexcept {
base::operator=(d);
return *this;
}
VarArray &operator*=(T fac) noexcept {
base::operator*=(fac);
return *this;
}
VarArray &operator/=(T fac) noexcept {
base::operator/=(fac);
return *this;
}
VarArray &operator+=(T fac) noexcept {
base::operator+=(fac);
return *this;
}
VarArray &operator-=(T fac) noexcept {
base::operator-=(fac);
return *this;
}
};
template <typename T, int D> class VarArrayBase {
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;
// 构造函数和拷贝函数
VarArrayBase() = default;
VarArrayBase(std::initializer_list<index_t> dimList);
VarArrayBase(const VarArrayBase &src);
VarArrayBase(VarArrayBase &&src);
VarArrayBase &operator=(const VarArrayBase &src);
VarArrayBase &operator=(VarArrayBase &&src);
template <typename... Dims> VarArrayBase(Dims... dims);
~VarArrayBase() { 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];
}
inline const T &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... dimensions>
bool ReConstruct(dimensions... dims) noexcept {
static_assert(D == sizeof...(dimensions), "not matched\n");
dim = {dims...};
sz = CalcSize();
delete[] elem;
return elem = new T[sz];
}
// 跟复制函数是不同的,复制函数会清空原来的内存
inline void CopyValueFrom(const VarArrayBase &src) noexcept;
inline void MoveValueFrom(VarArrayBase &&src) noexcept;
// 修改状态而不返回
inline void AssignValue(T val) noexcept;
// template<typename T, int D, int options>
inline void operator=(T d) noexcept;
inline void operator*=(T fac) noexcept;
inline void operator/=(T fac) noexcept;
inline void operator+=(T fac) noexcept;
inline void 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:
protected:
// 默认从0开始
std::array<int, D> dim{};
index_t sz{};
T *elem{};
// 添加引用指针试一试
// mutable bool owner{true};
void copy_from(const VarArrayBase &src);
void move_from(VarArrayBase &src);
int CalcSize() noexcept {
int tmp{1};
for (int i = 0; i < D; ++i)
tmp *= dim[i];
return tmp;
}
};
template <typename T, int D>
void VarArrayBase<T, D>::copy_from(const VarArrayBase &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 VarArrayBase<T, D>::move_from(VarArrayBase &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>
VarArrayBase<T, D>::VarArrayBase(
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>
VarArrayBase<T, D>::VarArrayBase(const VarArrayBase &src) {
copy_from(src);
}
// 移动构造函数
template <typename T, int D>
VarArrayBase<T, D>::VarArrayBase(VarArrayBase &&src) {
move_from(src);
}
template <typename T, int D>
template <typename... Dims>
inline VarArrayBase<T, D>::VarArrayBase(Dims... dims) : dim{dims...} {
static_assert(D == sizeof...(Dims), "not matched\n");
// 这能运行
// auto tmp{(... * dims)};
sz = CalcSize();
elem = new T[sz];
}
// 赋值运算符
template <typename T, int D>
VarArrayBase<T, D> &VarArrayBase<T, D>::
operator=(const VarArrayBase &src) {
if (this == &src)
return *this;
delete[] elem;
copy_from(src);
return *this;
}
// 移动赋值运算符
template <typename T, int D>
VarArrayBase<T, D> &VarArrayBase<T, D>::
operator=(VarArrayBase &&src) {
if (this == &src)
return src;
delete[] elem;
move_from(src);
}
template <typename T, int D>
void VarArrayBase<T, D>::CopyValueFrom(
const VarArrayBase &src) noexcept {
if (this == &src)
return;
assert(dim == src.dim);
memcpy(elem, src.elem, sizeof(T) * sz);
}
template <typename T, int D>
void VarArrayBase<T, D>::MoveValueFrom(VarArrayBase &&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>
void VarArrayBase<T, D>::AssignValue(T val) noexcept {
for (index_t i = 0; i < sz; ++i)
elem[i] = val;
}
template <typename T, int D>
void VarArrayBase<T, D>::operator*=(T fac) noexcept {
for (index_t i = 0; i < sz; ++i)
elem[i] *= fac;
}
template <typename T, int D>
void VarArrayBase<T, D>::operator/=(T fac) noexcept {
for (index_t i = 0; i < sz; ++i)
elem[i] /= fac;
}
template <typename T, int D>
void VarArrayBase<T, D>::operator+=(T fac) noexcept {
for (index_t i = 0; i < sz; ++i)
elem[i] += fac;
}
template <typename T, int D>
void VarArrayBase<T, D>::operator-=(T fac) noexcept {
for (index_t i = 0; i < sz; ++i)
elem[i] -= fac;
}
template <typename T, int D>
void VarArrayBase<T, D>::operator=(T d) noexcept {
for (index_t i = 0; i < sz; ++i)
elem[i] = d;
}
// } // namespace VarArray_new
#endif
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。