[ox/model] Add modelops with copy, move, and equals
This commit is contained in:
parent
2dc9ce4015
commit
24f26d822a
1
deps/ox/src/ox/model/model.hpp
vendored
1
deps/ox/src/ox/model/model.hpp
vendored
@ -11,5 +11,6 @@
|
|||||||
#include "descread.hpp"
|
#include "descread.hpp"
|
||||||
#include "desctypes.hpp"
|
#include "desctypes.hpp"
|
||||||
#include "descwrite.hpp"
|
#include "descwrite.hpp"
|
||||||
|
#include "modelops.hpp"
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
#include "walk.hpp"
|
#include "walk.hpp"
|
||||||
|
286
deps/ox/src/ox/model/modelops.hpp
vendored
Normal file
286
deps/ox/src/ox/model/modelops.hpp
vendored
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 - 2021 gary@drinkingtea.net
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ox/std/error.hpp>
|
||||||
|
#include <ox/std/types.hpp>
|
||||||
|
#include <ox/std/utility.hpp>
|
||||||
|
|
||||||
|
#include "types.hpp"
|
||||||
|
|
||||||
|
namespace ox {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<std::size_t size>
|
||||||
|
class MemberList {
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::size_t m_i = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void *vars[size];
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr Error field(const char*, T *v) noexcept {
|
||||||
|
vars[m_i++] = static_cast<void*>(v);
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr Error field(const char*, T *v, int) noexcept {
|
||||||
|
vars[m_i++] = static_cast<void*>(v);
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
constexpr Error field(const char*, UnionView<U> u) noexcept {
|
||||||
|
vars[m_i++] = static_cast<void*>(u.get());
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr Error field(const char *name, SerStr s) noexcept {
|
||||||
|
return field(name, s.target());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T = void>
|
||||||
|
constexpr void setTypeInfo(const char* = T::TypeName, int = T::Fields) noexcept {
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
static constexpr auto opType() noexcept {
|
||||||
|
return "GetMembers";
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<std::size_t size>
|
||||||
|
class Copier {
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::size_t m_i = 0;
|
||||||
|
MemberList<size> *m_dst = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr Copier(MemberList<size> *dst) noexcept: m_dst(dst) {
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FT>
|
||||||
|
constexpr Error field(const char *name, const FT *v) noexcept {
|
||||||
|
if constexpr(isVector(v)) {
|
||||||
|
return field(name, v->data(), v->size());
|
||||||
|
} else {
|
||||||
|
auto &src = *v;
|
||||||
|
auto &dst = *cbit_cast<FT*>(m_dst->vars[m_i]);
|
||||||
|
dst = src;
|
||||||
|
++m_i;
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FT>
|
||||||
|
constexpr Error field(const char*, const FT *list, int elements) {
|
||||||
|
for (auto i = 0l; i < elements; ++i) {
|
||||||
|
auto &src = list[i];
|
||||||
|
auto &dst = cbit_cast<FT*>(m_dst->vars[m_i])[i];
|
||||||
|
dst = src;
|
||||||
|
}
|
||||||
|
++m_i;
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
constexpr Error field(const char*, UnionView<U> u) {
|
||||||
|
auto &dst = *cbit_cast<U*>(m_dst->vars[m_i]);
|
||||||
|
auto &src = *u.get();
|
||||||
|
dst = src;
|
||||||
|
++m_i;
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr Error field(const char *name, SerStr s) {
|
||||||
|
return field(name, s.target());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T = void>
|
||||||
|
constexpr void setTypeInfo(const char* = T::TypeName, int = T::Fields) {
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
static constexpr auto opType() {
|
||||||
|
return "Copy";
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<std::size_t size>
|
||||||
|
class Mover {
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::size_t m_i = 0;
|
||||||
|
MemberList<size> *m_dst = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr Mover(MemberList<size> *dst) noexcept: m_dst(dst) {
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FT>
|
||||||
|
constexpr Error field(const char *name, FT *v) noexcept {
|
||||||
|
if constexpr(isVector(v)) {
|
||||||
|
return field(name, v->data(), v->size());
|
||||||
|
} else {
|
||||||
|
auto &src = *v;
|
||||||
|
auto &dst = *cbit_cast<FT*>(m_dst->vars[m_i]);
|
||||||
|
dst = move(src);
|
||||||
|
src = FT{};
|
||||||
|
++m_i;
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FT>
|
||||||
|
constexpr Error field(const char*, FT *list, int elements) noexcept {
|
||||||
|
for (auto i = 0l; i < elements; ++i) {
|
||||||
|
auto &src = list[i];
|
||||||
|
auto &dst = cbit_cast<FT*>(m_dst->vars[m_i])[i];
|
||||||
|
dst = move(src);
|
||||||
|
src = FT{};
|
||||||
|
}
|
||||||
|
++m_i;
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
constexpr Error field(const char*, UnionView<U> u) noexcept {
|
||||||
|
auto &dst = *cbit_cast<U*>(m_dst->vars[m_i]);
|
||||||
|
auto &src = *u.get();
|
||||||
|
dst = move(src);
|
||||||
|
++m_i;
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr Error field(const char *name, SerStr s) noexcept {
|
||||||
|
return field(name, s.target());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T = void>
|
||||||
|
constexpr void setTypeInfo(const char* = T::TypeName, int = T::Fields) noexcept {
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
static constexpr auto opType() noexcept {
|
||||||
|
return "Copy";
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<std::size_t size>
|
||||||
|
class Equals {
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::size_t m_i = 0;
|
||||||
|
MemberList<size> *m_dst = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool value = false;
|
||||||
|
|
||||||
|
constexpr Equals(MemberList<size> *dst) noexcept: m_dst(dst) {
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FT>
|
||||||
|
constexpr Error field(const char *name, const FT *v) noexcept {
|
||||||
|
if constexpr(isVector(v)) {
|
||||||
|
return field(name, v->data(), v->size());
|
||||||
|
} else {
|
||||||
|
auto &src = *v;
|
||||||
|
auto &dst = *cbit_cast<FT*>(m_dst->vars[m_i]);
|
||||||
|
++m_i;
|
||||||
|
if (dst == src) {
|
||||||
|
return OxError(0);
|
||||||
|
} else {
|
||||||
|
this->value = false;
|
||||||
|
return OxError(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FT>
|
||||||
|
constexpr Error field(const char*, const FT *list, int elements) noexcept {
|
||||||
|
for (auto i = 0l; i < elements; ++i) {
|
||||||
|
auto &src = list[i];
|
||||||
|
auto &dst = cbit_cast<FT*>(m_dst->vars[m_i])[i];
|
||||||
|
if (!(dst == src)) {
|
||||||
|
this->value = false;
|
||||||
|
return OxError(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++m_i;
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
constexpr Error field(const char*, UnionView<U> u) noexcept {
|
||||||
|
auto &dst = *cbit_cast<U*>(m_dst->vars[m_i]);
|
||||||
|
auto &src = *u.get();
|
||||||
|
++m_i;
|
||||||
|
if (dst == src) {
|
||||||
|
return OxError(0);
|
||||||
|
} else {
|
||||||
|
this->value = false;
|
||||||
|
return OxError(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr Error field(const char *name, SerStr s) noexcept {
|
||||||
|
return field(name, s.target());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T = void>
|
||||||
|
constexpr void setTypeInfo(const char* = T::TypeName, int = T::Fields) noexcept {
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
static constexpr auto opType() noexcept {
|
||||||
|
return "Copy";
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr void moveModel(T *dst, T *src) noexcept {
|
||||||
|
constexpr auto size = T::Fields;
|
||||||
|
detail::MemberList<size> dstFields;
|
||||||
|
detail::Mover<size> mover(&dstFields);
|
||||||
|
oxIgnoreError(model(&dstFields, dst));
|
||||||
|
oxIgnoreError(model(&mover, src));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr void copyModel(T *dst, const T *src) noexcept {
|
||||||
|
constexpr auto size = T::Fields;
|
||||||
|
detail::MemberList<size> dstFields;
|
||||||
|
detail::Copier<size> copier(&dstFields);
|
||||||
|
oxIgnoreError(model(&dstFields, dst));
|
||||||
|
oxIgnoreError(model(&copier, src));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr bool equalsModel(T *a, T *b) noexcept {
|
||||||
|
constexpr auto size = T::Fields;
|
||||||
|
detail::MemberList<size> aFields;
|
||||||
|
detail::Equals<size> equals(&aFields);
|
||||||
|
oxIgnoreError(model(&aFields, a));
|
||||||
|
oxIgnoreError(model(&equals, b));
|
||||||
|
return equals.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
8
deps/ox/src/ox/model/optype.hpp
vendored
8
deps/ox/src/ox/model/optype.hpp
vendored
@ -23,22 +23,22 @@ namespace OpType {
|
|||||||
// empty default implementations of model functions
|
// empty default implementations of model functions
|
||||||
|
|
||||||
template<typename T, typename O>
|
template<typename T, typename O>
|
||||||
Error modelRead(T*, O*) {
|
constexpr Error modelRead(T*, O*) {
|
||||||
return OxError(1, "Model: modelRead not implemented");
|
return OxError(1, "Model: modelRead not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename O>
|
template<typename T, typename O>
|
||||||
Error modelWrite(T*, O*) {
|
constexpr Error modelWrite(T*, O*) {
|
||||||
return OxError(1, "Model: modelWrite not implemented");
|
return OxError(1, "Model: modelWrite not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename O>
|
template<typename T, typename O>
|
||||||
Error modelWriteDefinition(T*, O*) {
|
constexpr Error modelWriteDefinition(T*, O*) {
|
||||||
return OxError(1, "Model: modelWriteDefinition not implemented");
|
return OxError(1, "Model: modelWriteDefinition not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename O>
|
template<typename T, typename O>
|
||||||
Error model(T *io, O *obj) {
|
constexpr Error model(T *io, O *obj) {
|
||||||
Error err;
|
Error err;
|
||||||
if constexpr(ox_strcmp(T::opType(), ox::OpType::Read) == 0) {
|
if constexpr(ox_strcmp(T::opType(), ox::OpType::Read) == 0) {
|
||||||
err = modelRead(io, obj);
|
err = modelRead(io, obj);
|
||||||
|
44
deps/ox/src/ox/model/types.hpp
vendored
44
deps/ox/src/ox/model/types.hpp
vendored
@ -8,13 +8,46 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#if __has_include(<vector>)
|
||||||
|
#include <vector>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_include(<QVector>)
|
||||||
|
#include <QVector>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <ox/std/bstring.hpp>
|
#include <ox/std/bstring.hpp>
|
||||||
#include <ox/std/strops.hpp>
|
#include <ox/std/strops.hpp>
|
||||||
#include <ox/std/types.hpp>
|
#include <ox/std/types.hpp>
|
||||||
#include <ox/std/typetraits.hpp>
|
#include <ox/std/typetraits.hpp>
|
||||||
|
#include <ox/std/vector.hpp>
|
||||||
|
|
||||||
namespace ox {
|
namespace ox {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr bool isVector(const T&) noexcept {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr bool isVector(const Vector<T>*) noexcept {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __has_include(<vector>)
|
||||||
|
template<typename T>
|
||||||
|
constexpr bool isVector(const std::vector<T>*) noexcept {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_include(<QVector>)
|
||||||
|
template<typename T>
|
||||||
|
constexpr bool isVector(const QVector<T>*) noexcept {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
class SerStr {
|
class SerStr {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -46,10 +79,16 @@ class SerStr {
|
|||||||
m_cap = cap;
|
m_cap = cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
constexpr const char *c_str() const noexcept {
|
constexpr const char *c_str() const noexcept {
|
||||||
return m_str;
|
return m_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr auto target() const noexcept {
|
||||||
|
return m_tgt;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr char *data(std::size_t sz = 0) noexcept {
|
constexpr char *data(std::size_t sz = 0) noexcept {
|
||||||
if (m_tgt && sz) {
|
if (m_tgt && sz) {
|
||||||
*m_tgt = new char[sz];
|
*m_tgt = new char[sz];
|
||||||
@ -59,10 +98,12 @@ class SerStr {
|
|||||||
return m_str;
|
return m_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
constexpr int len() const noexcept {
|
constexpr int len() const noexcept {
|
||||||
return static_cast<int>(m_str ? ox_strlen(m_str) : 0);
|
return static_cast<int>(m_str ? ox_strlen(m_str) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
constexpr int cap() const noexcept {
|
constexpr int cap() const noexcept {
|
||||||
return m_cap;
|
return m_cap;
|
||||||
}
|
}
|
||||||
@ -80,14 +121,17 @@ class UnionView {
|
|||||||
constexpr UnionView(Union *u, int idx) noexcept: m_idx(idx), m_union(u) {
|
constexpr UnionView(Union *u, int idx) noexcept: m_idx(idx), m_union(u) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
constexpr auto idx() const noexcept {
|
constexpr auto idx() const noexcept {
|
||||||
return m_idx;
|
return m_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
constexpr const Union *get() const noexcept {
|
constexpr const Union *get() const noexcept {
|
||||||
return m_union;
|
return m_union;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
constexpr Union *get() noexcept {
|
constexpr Union *get() noexcept {
|
||||||
return m_union;
|
return m_union;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user