diff --git a/.development/test_new.cpp b/.development/test_new.cpp index ef8bbea..516baf4 100644 --- a/.development/test_new.cpp +++ b/.development/test_new.cpp @@ -1,5 +1,19 @@ +/* +g++ test_new.cpp -std=c++20 -g -Wall -Wpedantic -Wextra -Wconversion +-Wconversion -Wunitialized -Wshadow -Wmissing-declarations +-Wimplicit-fallthrough +-Wduplicated-cond +-Wsign-compare +-Wformat +-Wnull-dereference +-Wdeprecated +-Wstrict-aliasing +*/ #define STANDALONE_ETR #include "../inst/include/etr_bits/Core.hpp" +#include "../inst/include/etr_bits/BufferVector.hpp" +#include "../inst/include/etr_bits/BinaryCalculations.hpp" +#include "../inst/include/etr_bits/UnaryCalculations.hpp" using namespace etr; int main() { @@ -11,5 +25,14 @@ int main() { Borrow b(ptr, 5); std::cout << b << std::endl; + Vec vec(SI{10}); + std::cout << vec.size() << std::endl; + for (auto& i: vec) i = 3.14; + vec = -(vec + vec); + std::cout << vec << std::endl; + + + vec[0] = 10; + delete[] ptr; } diff --git a/inst/include/etr_bits/BinaryCalculations.hpp b/inst/include/etr_bits/BinaryCalculations.hpp index fc1fd95..e22e4e1 100644 --- a/inst/include/etr_bits/BinaryCalculations.hpp +++ b/inst/include/etr_bits/BinaryCalculations.hpp @@ -3,25 +3,14 @@ #include "Core.hpp" -// TODO: what is needed in order that for loops work with Operations -/* -RetType* p; -auto begin() const { - return It{p}; -} -auto end() const { - return It{p + this -> size()}; -} -*/ - namespace etr { -template +template struct BinaryOperation { - using Type = DoubleTrait; - using TypeTrait = Trait; - using CaseTrait = BinaryTrait; - using RetType = typename CTrait::RetType; + using Trait = BTrait; + // TODO: the identification of RetType misses the fact that it is bool if + // BTrait is part of the Comparison Traits + using RetType = std::common_type_t; const L &l; const R &r; using typeTraitL = L; @@ -39,12 +28,10 @@ struct BinaryOperation { } else { return l.im() || r.im(); } - return false; // TODO: correct? + return false; } std::size_t nc() const { if constexpr (IsArithV) { - // TODO: check whether one has to add here the test whether R and L are - // matrices. Same is true for nr return r.nc(); } else if constexpr (IsArithV) { return l.nc(); @@ -88,14 +75,14 @@ struct BinaryOperation { // TODO: are all of those constructors required? // Actually only BinaryOperation(const L &l_, const R &r_) : l(l_), r(r_) {} // is used. - BinaryOperation(const BinaryOperation &other) : l(other.l), r(other.r) {} - BinaryOperation(const BinaryOperation &&other) - : l(std::move(other.l)), r(std::move(other.r)) {} + // BinaryOperation(const BinaryOperation &other) : l(other.l), r(other.r) {} + // BinaryOperation(const BinaryOperation &&other) + // : l(std::move(other.l)), r(std::move(other.r)) {} BinaryOperation(const L &l_, const R &r_) : l(l_), r(r_) {} - template - BinaryOperation(const BinaryOperation - &other) // TODO: needs move constructor - : l(other.l), r(other.r) {} + // template + // BinaryOperation(const BinaryOperation + // &other) // TODO: needs move constructor + // : l(other.l), r(other.r) {} auto operator[](std::size_t i) const { constexpr bool isDoubleL = IsArithV; @@ -132,21 +119,6 @@ struct BinaryOperation { mp.setMatrix(mp_.ismatrix, mp_.rows, mp_.cols); } - template static std::size_t getSize(AV &av) { - using TyL = typename ReRef::type; - using TyR = typename ReRef::type; - return TyL::getSize(av) > TyR::getSize(av) ? TyL::getSize(av) - : TyR::getSize(av); - } - template - static RetType getVal(AV &av, - std::size_t VecIdx) { // issue: how to handle scalar - // types? Or temporary types? - using TyL = typename ReRef::type; - using TyR = typename ReRef::type; - return f(TyL::template getVal(av, VecIdx % TyL::getSize(av)), - TyR::template getVal(av, VecIdx % TyR::getSize(av))); - } }; template auto operator+(const L &l, const R &r) { diff --git a/inst/include/etr_bits/Core/BaseStore.hpp b/inst/include/etr_bits/Core/BaseStore.hpp index 02e57e0..240c8b6 100644 --- a/inst/include/etr_bits/Core/BaseStore.hpp +++ b/inst/include/etr_bits/Core/BaseStore.hpp @@ -101,7 +101,7 @@ template struct BaseStore { }; #endif BaseStore(std::size_t sz_) - : sz(sz_), capacity(static_cast(sz_ * 1.15)) { + : sz(sz_), capacity(static_cast(static_cast(sz_)* 1.15)) { ass<"Size has to be larger than 0!">(sz_ > 0); p = new T[capacity]; for (std::size_t i = 0; i < capacity; i++) { @@ -111,7 +111,7 @@ template struct BaseStore { } BaseStore(int sz_) : sz(static_cast(sz_)), - capacity(static_cast(sz_ * 1.15)) { + capacity(static_cast(static_cast(sz_) * 1.15)) { ass<"Size has to be larger than 0!!">(sz_ > 0); p = new T[capacity]; for (std::size_t i = 0; i < sz; i++) @@ -140,7 +140,7 @@ template struct BaseStore { } template - requires(IsArithV>) + requires(IsArithV) void fill(TInp &&val) { if constexpr (IS) { std::fill(p, p + sz, val); @@ -150,7 +150,9 @@ template struct BaseStore { } } - template void fill(TInp &&inp) { + template +requires (!IsArithV) + void fill(TInp &&inp) { ass<"cannot use fill with vectors of different lengths">(inp.size() == sz); using DataType = typename ExtractDataType>::RetType; @@ -251,12 +253,12 @@ template struct BaseStore { p = nullptr; } sz = size; - capacity = static_cast(1.15 * sz); + capacity = static_cast(1.15 * static_cast(sz)); p = new T[capacity]; allocated = true; } void resize(std::size_t newSize) { - ass<"Size has to be larger than 0!!!">(newSize >= 0); + ass<"Size has to be larger than 0!!!">(newSize > 0); if (!allocated) { init(newSize); fill(T()); @@ -265,7 +267,7 @@ template struct BaseStore { if (newSize > capacity) { ass<"try to delete nullptr">(p != nullptr); delete[] p; - capacity = static_cast(newSize * 1.15); + capacity = static_cast(static_cast(newSize) * 1.15); p = new T[capacity]; sz = newSize; allocated = true; @@ -278,25 +280,26 @@ template struct BaseStore { } RetType operator[](std::size_t idx) const { - // TODO: can ass be faster? ass<"No memory was allocated">(allocated); - ass<"Error: out of boundaries --> value below 1">(idx >= 0); - ass<"Error: out of boundaries --> value beyond size of vector">(idx < sz); + // NOTE: negative idx leads to overflow and + // is than the max possible value of std::size_t + ass<"Error: out of boundaries">(idx < sz); return p[idx]; } - // TODO: check with static_asssert that this is never called for const T + // TODO: update the assertions for all operator[] RetType &operator[](std::size_t idx) { ass<"No memory was allocated">(allocated); - ass<"Error: out of boundaries --> value below 1">(idx >= 0); + // NOTE: negative idx leads to overflow and + // is than the max possible value of std::size_t ass<"Error: out of boundaries --> value beyond size of vector">(idx < sz); return p[idx]; } template void moveit(L2 &other) { T *temporary = other.p; - int tempSize = other.sz; - int tempCapacity = other.capacity; + std::size_t tempSize = other.sz; + std::size_t tempCapacity = other.capacity; other.p = this->p; other.sz = this->sz; other.capacity = this->capacity; diff --git a/inst/include/etr_bits/Core/Borrow.hpp b/inst/include/etr_bits/Core/Borrow.hpp index a8f0747..6534bef 100644 --- a/inst/include/etr_bits/Core/Borrow.hpp +++ b/inst/include/etr_bits/Core/Borrow.hpp @@ -58,16 +58,16 @@ template struct Borrow { }; Borrow(std::size_t r, std::size_t c) = delete; Borrow(std::size_t r, std::size_t c, const double value) = delete; - Borrow(T *p, std::size_t sz) { - this->p = p; - this->sz = sz; + Borrow(T *p_, std::size_t sz_) { + this->p = p_; + this->sz = sz_; capacity = sz; this->allocated = true; } - void init(T *p, std::size_t sz) { - this->p = p; - this->sz = sz; + void init(T *p_, std::size_t sz_) { + this->p = p_; + this->sz = sz_; capacity = sz; this->allocated = true; } diff --git a/inst/include/etr_bits/Core/Concepts.hpp b/inst/include/etr_bits/Core/Concepts.hpp index 44d4385..2307f19 100644 --- a/inst/include/etr_bits/Core/Concepts.hpp +++ b/inst/include/etr_bits/Core/Concepts.hpp @@ -15,12 +15,20 @@ concept isBID = requires { requires IS || IS || IS; }; + +// Test R class +// =================================================================== template concept IsSubset = requires { typename ReRef::type::Trait; requires IS::type::Trait, SubsetTrait>; }; template +concept IsSubsetClass = requires { + typename ReRef::type::Trait; + requires IS::type::Trait, SubsetClassTrait>; +}; +template concept IsLBuffer = requires { typename ReRef::type::Trait; requires IS::type::Trait, LBufferTrait>; @@ -30,13 +38,21 @@ concept IsRBuffer = requires { typename ReRef::type::Trait; requires IS::type::Trait, RBufferTrait>; }; +template +concept IsBorrow = requires { + typename ReRef::type::Trait; + requires IS::type::Trait, BorrowTrait>; +}; +template +concept IsBorrowSEXP = requires { + typename ReRef::type::Trait; + requires IS::type::Trait, BorrowSEXPTrait>; +}; template concept IsUnary = requires { typename ReRef::type::Trait; - requires IS< - typename ReRef::type::Trait, - SinusTrait> || + requires IS::type::Trait, SinusTrait> || IS::type::Trait, ASinusTrait> || IS::type::Trait, SinusHTrait> || IS::type::Trait, CosinusTrait> || @@ -52,22 +68,22 @@ concept IsUnary = requires { }; template concept IsBinary = requires { - typename ReRef::type::Trait; - requires IS< - typename ReRef::type::Trait, - PlusTrait> || - IS::type::Trait, MinusTrait> || - IS::type::Trait, TimesTrait> || - IS::type::Trait, DivideTrait> || - IS::type::Trait, PowTrait> || - IS::type::Trait, EqualTrait> || - IS::type::Trait, SmallerTrait> || - IS::type::Trait, SmallerEqualTrait> || - IS::type::Trait, LargerTrait> || - IS::type::Trait, LargerEqualTrait> || - IS::type::Trait, UnEqualTrait>; + typename ReRef::type::Trait; + requires IS::type::Trait, PlusTrait> || + IS::type::Trait, MinusTrait> || + IS::type::Trait, TimesTrait> || + IS::type::Trait, DivideTrait> || + IS::type::Trait, PowTrait> || + IS::type::Trait, EqualTrait> || + IS::type::Trait, SmallerTrait> || + IS::type::Trait, SmallerEqualTrait> || + IS::type::Trait, LargerTrait> || + IS::type::Trait, LargerEqualTrait> || + IS::type::Trait, UnEqualTrait>; }; +// Test Vec class +// =================================================================== template concept IsLBufferVec = requires(T t) { typename T::DType; @@ -84,6 +100,9 @@ concept IsSubsetVec = requires(T t) { requires IsSubset; }; +// Test Input class +// =================================================================== +// Vector template struct is_vec: std::false_type {}; @@ -95,13 +114,29 @@ inline constexpr bool is_vec_v = is_vec ::value; template concept IsVec = is_vec_v; - template concept IsRVec = requires(T t) { typename T::DType; requires IsVec && IsRBuffer; }; + +// Binary +template +struct is_binary_operation : std::false_type {}; + +template +struct is_binary_operation> + : std::bool_constant> {}; + +template +inline constexpr bool is_binary_operation_v = is_binary_operation::value; + +template +concept IsBinaryOperation = is_binary_operation_v; + + + } // namespace etr #endif diff --git a/inst/include/etr_bits/Core/Types.hpp b/inst/include/etr_bits/Core/Types.hpp index 11434de..b452e13 100644 --- a/inst/include/etr_bits/Core/Types.hpp +++ b/inst/include/etr_bits/Core/Types.hpp @@ -1,3 +1,9 @@ +// TODO: add the iterator to each class: Buffer, Subset, Binary, Unary, Borrow, BorrowSEXP +// Directly use the iterator methods begin, end etc. in Vec +// Replace BaseStore with Buffer. +// Each class has to possess RetType and Trait + + #ifndef TYPES_ETR_H #define TYPES_ETR_H @@ -13,13 +19,14 @@ template struct BorrowSEXP; template struct Borrow; template struct Subset; +template struct SubsetClass; template struct Buffer; template > struct Vec; -template +template struct BinaryOperation; -template +template struct UnaryOperation; template struct ExtractDataType; diff --git a/inst/include/etr_bits/Core/Utils.hpp b/inst/include/etr_bits/Core/Utils.hpp index 20cb3d2..a8c26df 100644 --- a/inst/include/etr_bits/Core/Utils.hpp +++ b/inst/include/etr_bits/Core/Utils.hpp @@ -101,9 +101,9 @@ template inline void warn(bool inp) { struct SI { std::size_t sz = 0; - SI(const std::size_t sz) : sz(sz) {} - SI(const int sz) : sz(static_cast(sz)) {} - SI(const long long sz) : sz(static_cast(sz)) {} + SI(const std::size_t sz_) : sz(sz_) {} + SI(const int sz_) : sz(static_cast(sz_)) {} + SI(const long long sz_) : sz(static_cast(sz_)) {} }; } // namespace etr diff --git a/inst/include/etr_bits/UnaryCalculations.hpp b/inst/include/etr_bits/UnaryCalculations.hpp index 75286cb..b980319 100644 --- a/inst/include/etr_bits/UnaryCalculations.hpp +++ b/inst/include/etr_bits/UnaryCalculations.hpp @@ -2,15 +2,11 @@ #define UNARYOPERATION #include "Core.hpp" -#include "Core/Concepts.hpp" -#include "Core/Types.hpp" -#include namespace etr { -template struct UnaryOperation { - using RetType = typename CTrait::RetType; - using TypeTrait = Trait; - using CaseTrait = CTrait; +template struct UnaryOperation { + using Trait = UTrait; + using RetType = typename I::RetType; const I &obj; using typeTraitObj = I; MatrixParameter mp; @@ -83,7 +79,7 @@ template auto operator-(const T &obj) { constexpr bool isDouble = IsArithV; if constexpr (!isDouble) { return Vec::RetType, - UnaryOperation, UnaryTrait>( + UnaryOperation>( UnaryOperation(obj.d)); } else if constexpr (isDouble) { return Vec>( @@ -95,7 +91,7 @@ template auto sinus(const T &obj) { constexpr bool isDouble = IsArithV; if constexpr (!isDouble) { return Vec::RetType, - UnaryOperation, UnaryTrait>( + UnaryOperation>( UnaryOperation(obj.d)); } else if constexpr (isDouble) { return Vec>( @@ -112,7 +108,7 @@ template auto sinush(const T &obj) { constexpr bool isDouble = IsArithV; if constexpr (!isDouble) { return Vec::RetType, - UnaryOperation, UnaryTrait>( + UnaryOperation>( UnaryOperation(obj.d)); } else if constexpr (isDouble) { return Vec>( @@ -129,7 +125,7 @@ template auto asinus(const T &obj) { constexpr bool isDouble = IsArithV; if constexpr (!isDouble) { return Vec::RetType, - UnaryOperation, UnaryTrait>( + UnaryOperation>( UnaryOperation(obj.d)); } else if constexpr (isDouble) { return Vec>( @@ -146,7 +142,7 @@ template auto cosinus(const T &obj) { constexpr bool isDouble = IsArithV; if constexpr (!isDouble) { return Vec::RetType, - UnaryOperation, UnaryTrait>( + UnaryOperation>( UnaryOperation(obj.d)); } else if constexpr (isDouble) { return Vec>( @@ -163,7 +159,7 @@ template auto cosinush(const T &obj) { constexpr bool isDouble = IsArithV; if constexpr (!isDouble) { return Vec::RetType, - UnaryOperation, UnaryTrait>( + UnaryOperation>( UnaryOperation(obj.d)); } else if constexpr (isDouble) { return Vec>( @@ -180,7 +176,7 @@ template auto acosinus(const T &obj) { constexpr bool isDouble = IsArithV; if constexpr (!isDouble) { return Vec::RetType, - UnaryOperation, UnaryTrait>( + UnaryOperation>( UnaryOperation(obj.d)); } else if constexpr (isDouble) { return Vec>( @@ -197,7 +193,7 @@ template auto tangens(const T &obj) { constexpr bool isDouble = IsArithV; if constexpr (!isDouble) { return Vec::RetType, - UnaryOperation, UnaryTrait>( + UnaryOperation>( UnaryOperation(obj.d)); } else if constexpr (isDouble) { return Vec>( @@ -214,7 +210,7 @@ template auto tangensh(const T &obj) { constexpr bool isDouble = IsArithV; if constexpr (!isDouble) { return Vec::RetType, - UnaryOperation, UnaryTrait>( + UnaryOperation>( UnaryOperation(obj.d)); } else if constexpr (isDouble) { return Vec>( @@ -231,7 +227,7 @@ template auto atangens(const T &obj) { constexpr bool isDouble = IsArithV; if constexpr (!isDouble) { return Vec::RetType, - UnaryOperation, UnaryTrait>( + UnaryOperation>( UnaryOperation(obj.d)); } else if constexpr (isDouble) { return Vec>( @@ -248,7 +244,7 @@ template auto ln(const T &obj) { constexpr bool isDouble = IsArithV; if constexpr (!isDouble) { return Vec::RetType, - UnaryOperation, UnaryTrait>( + UnaryOperation>( UnaryOperation(obj.d)); } else if constexpr (isDouble) { return Vec>( @@ -265,7 +261,7 @@ template auto sqroot(const T &obj) { constexpr bool isDouble = IsArithV; if constexpr (!isDouble) { return Vec::RetType, - UnaryOperation, UnaryTrait>( + UnaryOperation>( UnaryOperation(obj.d)); } else if constexpr (isDouble) { return Vec>( @@ -283,7 +279,7 @@ auto exp(const T &obj) { // TODO: update this in the documentation constexpr bool isDouble = IsArithV; if constexpr (!isDouble) { return Vec::RetType, - UnaryOperation, UnaryTrait>( + UnaryOperation>( UnaryOperation(obj.d)); } else if constexpr (isDouble) { return Vec>( diff --git a/inst/include/etr_bits/Vector/AssignmentOperator.hpp b/inst/include/etr_bits/Vector/AssignmentOperator.hpp deleted file mode 100644 index 8f8877f..0000000 --- a/inst/include/etr_bits/Vector/AssignmentOperator.hpp +++ /dev/null @@ -1,293 +0,0 @@ -#ifndef ASSING2VEC_ETR_H -#define ASSING2VEC_ETR_H - -#include "VectorClass.hpp" -#include - -template - requires IsArithV -Vec &operator=(const TD inp) { - static_assert(!isUnaryOP::value, "Cannot assign to unary calculation"); - static_assert(!isBinaryOP::value, "Cannot assign to binary calculation"); - static_assert(!isRVec::value, - "Cannot assign to an r value. E.g. c(1, 2, 3) <- 1"); - if constexpr (is) { - if constexpr (isSubset::value) { - for (std::size_t i = 0; i < d.ind.size(); i++) { - d[i] = inp; - } -#ifdef DERIV_ETR - for (std::size_t i = 0; i < d.ind.size(); i++) { - deriv[i] = 0; - } -#endif - } else if constexpr (isBorrow::value) { - d.sz = 1; - d[0] = inp; -#ifdef DERIV_ETR - deriv.resize(1); - deriv[0] = 0; -#endif - - } else { - d.resize(1); - d[0] = inp; -#ifdef DERIV_ETR - deriv.resize(1); - deriv[0] = 0; -#endif - } - return *this; - } else { - if constexpr (isSubset::value) { - for (std::size_t i = 0; i < d.ind.size(); i++) { - d[i] = static_cast(inp); - } -#ifdef DERIV_ETR - for (std::size_t i = 0; i < d.ind.size(); i++) { - deriv[i] = 0; - } -#endif - - } else if constexpr (isBorrow::value) { - d.sz = 1; - d[0] = static_cast(inp); -#ifdef DERIV_ETR - deriv.resize(1); - deriv[0] = 0; -#endif - - } else { - d.resize(1); - d[0] = static_cast(inp); -#ifdef DERIV_ETR - deriv.resize(1); - deriv[0] = 0; -#endif - } - return *this; - } -} - -Vec &operator=(const Vec &otherVec) { - - static_assert(!isUnaryOP::value, "Cannot assign to unary calculation"); - static_assert(!isBinaryOP::value, "Cannot assign to binary calculation"); - static_assert(!isRVec::value, - "Cannot assign to an r value. E.g. c(1, 2, 3) <- 1"); - - using DataTypeOtherVec = typename etr::ExtractDataType< - ReRef_t>::RetType; - if constexpr (isBuffer::value) { - temp.resize(otherVec.size()); - for (std::size_t i = 0; i < otherVec.size(); i++) { - if constexpr (is) { - temp[i] = otherVec[i]; - } else { - temp[i] = static_cast(otherVec[i]); - } - } - d.moveit(temp); - } else if constexpr (isBorrow::value) { - ass<"number of items to replace is not a multiple of replacement length">( - otherVec.size() <= d.capacity); - temp.resize(otherVec.size()); - for (std::size_t i = 0; i < otherVec.size(); i++) { - if constexpr (is) { - temp[i] = otherVec[i]; - } else { - temp[i] = static_cast(otherVec[i]); - } - } - ass<"size cannot be increased above the size of the borrowed object">( - d.sz <= otherVec.size()); - d.sz = otherVec.size(); - for (std::size_t i = 0; i < otherVec.size(); i++) - d[i] = temp[i]; - } else if constexpr (isBorrowSEXP::value) { - temp.resize(otherVec.size()); - for (std::size_t i = 0; i < otherVec.size(); i++) { - if constexpr (is) { - temp[i] = otherVec[i]; - } else { - temp[i] = static_cast(otherVec[i]); - } - } - if (otherVec.size() > this->size()) - d.resize(otherVec.size()); - - for (std::size_t i = 0; i < otherVec.size(); i++) - d[i] = temp[i]; - - } else if constexpr (isSubset::value) { - ass<"number of items to replace is not a multiple of replacement length">( - otherVec.size() == d.ind.size()); - temp.resize(otherVec.size()); - for (std::size_t i = 0; i < otherVec.size(); i++) { - if constexpr (is) { - temp[i] = otherVec[i]; - } else { - temp[i] = static_cast(otherVec[i]); - } - } - if (d.p->size() < temp.size()) - d.resize(temp.size()); - for (std::size_t i = 0; i < d.ind.size(); i++) { - d[i % d.ind.size()] = temp[i]; - } - } - if (otherVec.d.im()) { - d.setMatrix(true, otherVec.d.nr(), otherVec.d.nc()); - } - -#ifdef DERIV_ETR - // TODO: what if other Vec is subsetted - // deriv.resize(otherVec.size()); - // for (std::size_t i = 0; i < deriv.size(); i++) { - // deriv[i] = otherVec.deriv[i]; - // } - // TODO: is there something to do here? -#endif - - return *this; -} - -// TODO: finish this -template - requires(IsRVec> && IS && - isBuffer::value) -Vec &operator=(Vec &&otherVec) { - - static_assert(!isUnaryOP::value, "Cannot assign to unary calculation"); - static_assert(!isBinaryOP::value, "Cannot assign to binary calculation"); - static_assert(!isRVec::value, - "Cannot assign to an r value. E.g. c(1, 2, 3) <- 1"); - std::size_t tempSize = otherVec.size(); - std::size_t tempCapacity = otherVec.d.capacity; - T *tempP = otherVec.d.p; - bool allocated = otherVec.d.allocated; - - otherVec.d.allocated = d.allocated; - otherVec.d.sz = this->size(); - otherVec.d.capacity = d.capacity; - otherVec.d.p = d.p; - - d.allocated = allocated; - d.sz = tempSize; - d.capacity = tempCapacity; - d.p = tempP; - - if (otherVec.d.im()) { - d.setMatrix(true, otherVec.nr(), otherVec.nc()); - } -#ifdef DERIV_ETR - deriv.resize(this->size()); - for (std::size_t i = 0; i < deriv.size(); i++) { - deriv[i] = 0; - } -#endif - - return *this; -} - -template -Vec &operator=(const Vec &otherVec) { - - static_assert(!isUnaryOP::value, "Cannot assign to unary calculation"); - static_assert(!isBinaryOP::value, "Cannot assign to binary calculation"); - static_assert(!isRVec::value, - "Cannot assign to an r value. E.g. c(1, 2, 3) <- 1"); - using DataTypeOtherVec = typename etr::ExtractDataType< - ReRef_t>::RetType; - using typeOtherVec = ReRef_t; - if constexpr (isBuffer::value) { - - temp.resize(otherVec.size()); - for (std::size_t i = 0; i < otherVec.size(); i++) { - if constexpr (is) { - temp[i] = otherVec[i]; - } else { - temp[i] = static_cast(otherVec[i]); - } - } - d.moveit(temp); - } else if constexpr (isBorrow::value) { - ass<"number of items to replace is not a multiple of replacement length">( - otherVec.size() <= d.capacity); - temp.resize(otherVec.size()); - for (std::size_t i = 0; i < otherVec.size(); i++) { - if constexpr (is) { - temp[i] = otherVec[i]; - } else { - temp[i] = static_cast(otherVec[i]); - } - } - ass<"size cannot be increased above the size of the borrowed object">( - d.sz <= otherVec.size()); - d.sz = otherVec.size(); - for (std::size_t i = 0; i < otherVec.size(); i++) - d[i] = temp[i]; - } else if constexpr (isBorrowSEXP::value) { - temp.resize(otherVec.size()); - for (std::size_t i = 0; i < otherVec.size(); i++) { - if constexpr (is) { - temp[i] = otherVec[i]; - } else { - temp[i] = static_cast(otherVec[i]); - } - } - if (otherVec.size() > this->size()) - d.resize(otherVec.size()); - - for (std::size_t i = 0; i < otherVec.size(); i++) - d[i] = temp[i]; - - } else if constexpr (isSubset::value) { - ass<"number of items to replace is not a multiple of replacement length">( - otherVec.size() == d.ind.size()); - temp.resize(otherVec.size()); - for (std::size_t i = 0; i < otherVec.size(); i++) { - if constexpr (is) { - temp[i] = otherVec[i]; - } else { - temp[i] = static_cast(otherVec[i]); - } - } - for (std::size_t i = 0; i < d.ind.size(); i++) { - d[i % d.ind.size()] = temp[i]; - } - } - if (otherVec.d.im()) { - d.setMatrix(true, otherVec.d.nr(), otherVec.d.nc()); - } - -#ifdef DERIV_ETR - if constexpr (IsRVec> || - Operation) { - deriv.resize(this->size()); - // for (std::size_t i = 0; i < deriv.size(); i++) { - // deriv[i] = 0; - // } - } else { - // deriv.resize(otherVec.size()); - // for (std::size_t i = 0; i < deriv.sz; i++) { - // deriv[i] = otherVec.deriv[i]; - // } - } -#endif - - return *this; -} - -#ifdef STANDALONE_ETR -#else -Vec &operator=(SEXP s) { - d.initSEXP(s); -#ifdef DERIV_ETR - deriv.resize(d.sz); - deriv.fill(0.0); -#endif - return *this; -} -#endif -#endif diff --git a/inst/include/etr_bits/Vector/Constructors.hpp b/inst/include/etr_bits/Vector/Constructors.hpp deleted file mode 100644 index 73a638c..0000000 --- a/inst/include/etr_bits/Vector/Constructors.hpp +++ /dev/null @@ -1,486 +0,0 @@ -#ifndef CONSTRUCTORS_H -#define CONSTRUCTORS_H - -#include "VectorClass.hpp" - -template Vec(T2 n) = delete; - -#ifdef DERIV_ETR - -// TODO: maybe for some constructors the deriv.allocated can be set to false -// instead of allocating - -// NOTE: define Vector with specific size -explicit Vec(SI &sz) : d(sz.sz), deriv(sz.sz) {} -explicit Vec(SI &&sz) : d(sz.sz), deriv(sz.sz) {} - -// NOTE: Buffer -template -explicit Vec(const Buffer &&inp) : d(inp), deriv(inp) { - d.setMatrix(inp.mp); -} -template -explicit Vec(const Buffer &inp) : d(inp), deriv(inp) { - d.setMatrix(inp.mp); -} -template -explicit Vec(const Buffer &inp) : d(inp), deriv(inp) { - d.setMatrix(inp.mp); -} - -// NOTE: Borrow -template - requires IS> -explicit Vec(const Borrow &&borrowed) : d(borrowed), deriv(borrowed.sz) { - d.setMatrix(borrowed.mp); -} -template - requires IS> -explicit Vec(const Borrow &borrowed) : d(borrowed), deriv(borrowed.sz) { - d.setMatrix(borrowed.mp); -} -template - requires IS> -explicit Vec(T *ptr, std::size_t s) : d(ptr, s), deriv(s) {} - -// NOTE: BorrowSEXP -#ifdef STANDALONE_ETR -#else -template - requires IS> -explicit Vec(SEXP &&inp) = delete; - -template - requires IS> -explicit Vec(SEXP inp) : d(inp) { - deriv.resize(d.sz); - deriv.fill(0.0); -} -#endif - -// NOTE: Subset -template -explicit Vec(const Subset &&inp) : d(inp), deriv(inp.size()) { - d.setMatrix(inp.mp); -} -template -explicit Vec(Subset &inp) : d(inp), deriv(inp.size()) { - d.setMatrix(inp.mp); -} -// NOTE: Subset lazy -template - requires IS -explicit Vec(const SubsetClass &&inp) - : d(inp), deriv(inp.size()) { - d.setMatrix(inp.mp); -} -template - requires IS -explicit Vec(SubsetClass &inp) : d(inp), deriv(inp.size()) { - d.setMatrix(inp.mp); -} - -// NOTE: Binary operation -template -explicit Vec(const BinaryOperation &&inp) - : d(inp), deriv(inp.size()) { - using TypeTrait = OperationTrait; - d.setMatrix(inp.mp); -} -template // NOTE: only for comparison! -explicit Vec(const BinaryOperation &&inp) - : d(inp), deriv(inp.size()) { - using TypeTrait = OperationTrait; - d.setMatrix(inp.mp); -} -template -explicit Vec(BinaryOperation &inp) - : d(inp), deriv(inp.size()) { - using TypeTrait = OperationTrait; - d.setMatrix(inp.mp); -} - -// NOTE: Unary operation -template -explicit Vec(const UnaryOperation &&inp) - : d(inp), deriv(inp.size()) { - using TypeTrait = OperationTrait; - d.setMatrix(inp.mp); -} -template -explicit Vec(UnaryOperation &inp) - : d(inp), deriv(inp.size()) { - using TypeTrait = OperationTrait; - d.setMatrix(inp.mp); -} - -// NOTE: arithmetic constructors -explicit Vec(int sz) : d(1), deriv(1) { d[0] = static_cast(sz); } -explicit Vec(std::size_t sz) : d(1), deriv(1) { d[0] = sz; } -Vec(double sz) : d(1), deriv(1) { d[0] = sz; } -#ifdef STANDALONE_ETR -Vec(bool b) : d(1), deriv(1) { d[0] = static_cast(b); } -#else -// Vec(Rboolean b) : d(1), deriv(1) { d[0] = static_cast(b); } -#endif - -// NOTE: empty vector -explicit Vec() : d(), deriv() {} - -// NOTE: matrix constructors -explicit Vec(std::size_t rows, std::size_t cols) - : d(rows * cols), deriv(rows * cols) { - d.setMatrix(true, rows, cols); -} -explicit Vec(std::size_t rows, std::size_t cols, const double value) - : d(rows * cols), deriv(rows * cols) { - d.setMatrix(true, rows, cols); - d.fill(value); -} -// NOTE: other vector which is not of type RVec and has to be copied -template - requires IsVec> -Vec(const Vec &&other_vec) { - using TypeTrait = Trait2; - using CaseTrait = Trait2; - if constexpr (isBorrow::value) { - ass<"Sizes do not match">(d.sz <= - other_vec.size()); // FIX: is this correct? - d.sz = other_vec.size(); - for (std::size_t i = 0; i < d.size(); i++) { - d[i] = other_vec[i]; - } - if (other_vec.d.im()) { - d.setMatrix(true, other_vec.nr(), other_vec.nc()); - } - } else { - if (d.sz < other_vec.size()) { - this->d.resize(other_vec.size()); - } else { - d.sz = other_vec.size(); - } - for (std::size_t i = 0; i < d.size(); i++) { - d[i] = other_vec[i]; - } - if (other_vec.d.im()) { - d.setMatrix(true, other_vec.nr(), other_vec.nc()); - } - } - if (d.sz >= 1) { - deriv.resize(d.sz); - deriv.fill(1.0); - } -} - -// NOTE: other vector which is of type RVec and has different base type -template - requires(IsRVec> && !IS) -Vec(const Vec &&other_vec) { - using TypeTrait = Trait2; - using CaseTrait = Trait2; - if constexpr (isBorrow::value) { - ass<"Sizes do not match">(d.sz <= other_vec.size()); - d.sz = other_vec.size(); - for (std::size_t i = 0; i < d.size(); i++) { - d[i] = other_vec[i]; - } - if (other_vec.d.im()) { - d.setMatrix(true, other_vec.nr(), other_vec.nc()); - } - } else { - if (d.sz < other_vec.size()) { - this->d.resize(other_vec.size()); - } else { - d.sz = other_vec.size(); - } - for (std::size_t i = 0; i < d.size(); i++) { - d[i] = other_vec[i]; - } - if (other_vec.d.im()) { - d.setMatrix(true, other_vec.nr(), other_vec.nc()); - } - } - if (d.sz >= 1) { - deriv.resize(d.sz); - this->indep_var = other_vec.indep_var; - deriv.fill(0.0); - } -} - -// NOTE: other vector which is of type RVec and with same base type -template - requires(IsRVec> && IS) -Vec(Vec &&other_vec) { - using TypeTrait = Trait2; - using CaseTrait = Trait2; - if constexpr (isBorrow::value) { - ass<"Sizes do not match">(d.sz <= other_vec.size()); - d.sz = other_vec.size(); - for (std::size_t i = 0; i < d.size(); i++) { - d[i] = other_vec[i]; - } - if (other_vec.d.im()) { - d.setMatrix(true, other_vec.nr(), other_vec.nc()); - } - } else { - std::size_t tempSize = other_vec.size(); - d.allocated = other_vec.d.allocated; - other_vec.d.sz = this->size(); - d.sz = tempSize; - T *tempP = other_vec.d.p; - other_vec.d.p = d.p; - d.p = tempP; - if (other_vec.d.im()) { - d.setMatrix(true, other_vec.nr(), other_vec.nc()); - } - } - if (d.sz >= 1) { - deriv.resize(d.sz); - deriv.fill(0.0); - } -} - -// NOTE: pointer constructor -Vec(T *ptr, std::size_t size) : d(size), deriv(size) { - if constexpr (isBorrow::value) { - d.init(ptr, size); - } else if constexpr (isBuffer::value) { - for (std::size_t i = 0; i < size; i++) - d[i] = ptr[i]; - d.setMatrix(false, 0, 0); - } - deriv.fill(0.0); -} -Vec(BaseType *ptr, std::size_t rows, std::size_t cols) - : d(rows * cols), deriv(rows * cols) { - for (std::size_t i = 0; i < d.size(); i++) - d[i] = ptr[i]; - d.setMatrix(true, rows, cols); - deriv.fill(0.0); -} - -#else -// NOTE: define Vector with specific size -explicit Vec(SI &sz) : d(sz.sz) {} -explicit Vec(SI &&sz) : d(sz.sz) {} - -// NOTE: Buffer -template explicit Vec(const Buffer &&inp) : d(inp) { - d.setMatrix(inp.mp); -} -template explicit Vec(const Buffer &inp) : d(inp) { - d.setMatrix(inp.mp); -} -template -explicit Vec(const Buffer &inp) : d(inp) { - d.setMatrix(inp.mp); -} - -// NOTE: Borrow -template - requires IS> -explicit Vec(const Borrow &&borrowed) : d(borrowed) { - d.setMatrix(borrowed.mp); -} -template - requires IS> -explicit Vec(const Borrow &borrowed) : d(borrowed) { - d.setMatrix(borrowed.mp); -} -template - requires IS> -explicit Vec(T *ptr, std::size_t s) : d(ptr, s) {} - -// NOTE: BorrowSEXP -#ifdef STANDALONE_ETR -#else -template - requires IS> -explicit Vec(SEXP &&inp) = delete; - -template - requires IS> -explicit Vec(SEXP inp) : d(inp) {} -#endif - -// NOTE: Subset -template explicit Vec(const Subset &&inp) : d(inp) { - d.setMatrix(inp.mp); -} -template explicit Vec(Subset &inp) : d(inp) { - d.setMatrix(inp.mp); -} -// NOTE: Subset lazy -template - requires IS -explicit Vec(const SubsetClass &&inp) : d(std::move(inp)) { - d.setMatrix(inp.mp); -} -template - requires IS -explicit Vec(SubsetClass &inp) : d(std::move(inp)) { - d.setMatrix(inp.mp); -} - -// NOTE: Binary operation -template -explicit Vec(const BinaryOperation &&inp) : d(inp) { - using TypeTrait = OperationTrait; - d.setMatrix(inp.mp); -} -template // NOTE: only for comparison! -explicit Vec(const BinaryOperation &&inp) - : d(inp) { - using TypeTrait = OperationTrait; - d.setMatrix(inp.mp); -} -template -explicit Vec(BinaryOperation &inp) : d(inp) { - using TypeTrait = OperationTrait; - d.setMatrix(inp.mp); -} - -// NOTE: Unary operation -template -explicit Vec(const UnaryOperation &&inp) : d(inp) { - using TypeTrait = OperationTrait; - d.setMatrix(inp.mp); -} -template -explicit Vec(UnaryOperation &inp) : d(inp) { - using TypeTrait = OperationTrait; - d.setMatrix(inp.mp); -} - -// NOTE: arithmetic constructors -explicit Vec(int sz) : d(1) { d[0] = static_cast(sz); } -explicit Vec(std::size_t sz) : d(1) { d[0] = sz; } -Vec(double sz) : d(1) { d[0] = sz; } -#ifdef STANDALONE_ETR -Vec(bool b) : d(1) { d[0] = static_cast(b); } -#else -// Vec(Rboolean b) : d(1) { d[0] = static_cast(b); } -#endif - -// NOTE: empty vector -explicit Vec() : d() {} - -// NOTE: matrix constructors -explicit Vec(std::size_t rows, std::size_t cols) : d(rows * cols) { - d.setMatrix(true, rows, cols); -} -explicit Vec(std::size_t rows, std::size_t cols, const double value) - : d(rows * cols) { - d.setMatrix(true, rows, cols); - d.fill(value); -} -// NOTE: other vector which is not of type RVec and has to be copied -template - requires IsVec> -Vec(const Vec &&other_vec) { - using TypeTrait = Trait2; - using CaseTrait = Trait2; - if constexpr (isBorrow::value) { - ass<"Sizes do not match">(d.sz <= - other_vec.size()); // FIX: is this correct? - d.sz = other_vec.size(); - for (std::size_t i = 0; i < d.size(); i++) { - d[i] = other_vec[i]; - } - if (other_vec.d.im()) { - d.setMatrix(true, other_vec.nr(), other_vec.nc()); - } - } else { - if (d.sz < other_vec.size()) { - this->d.resize(other_vec.size()); - } else { - d.sz = other_vec.size(); - } - for (std::size_t i = 0; i < d.size(); i++) { - d[i] = other_vec[i]; - } - if (other_vec.d.im()) { - d.setMatrix(true, other_vec.nr(), other_vec.nc()); - } - } -} - -// NOTE: other vector which is of type RVec and has different base type -template - requires(IsRVec> && !IS) -Vec(const Vec &&other_vec) { - using TypeTrait = Trait2; - using CaseTrait = Trait2; - if constexpr (isBorrow::value) { - ass<"Sizes do not match">(d.sz <= other_vec.size()); - d.sz = other_vec.size(); - for (std::size_t i = 0; i < d.size(); i++) { - d[i] = other_vec[i]; - } - if (other_vec.d.im()) { - d.setMatrix(true, other_vec.nr(), other_vec.nc()); - } - } else { - if (d.sz < other_vec.size()) { - this->d.resize(other_vec.size()); - } else { - d.sz = other_vec.size(); - } - for (std::size_t i = 0; i < d.size(); i++) { - d[i] = other_vec[i]; - } - if (other_vec.d.im()) { - d.setMatrix(true, other_vec.nr(), other_vec.nc()); - } - } -} - -// NOTE: other vector which is of type RVec and with same base type -template - requires(IsRVec> && IS) -Vec(Vec &&other_vec) { - using TypeTrait = Trait2; - using CaseTrait = Trait2; - if constexpr (isBorrow::value) { - ass<"Sizes do not match">(d.sz <= other_vec.size()); - d.sz = other_vec.size(); - for (std::size_t i = 0; i < d.size(); i++) { - d[i] = other_vec[i]; - } - if (other_vec.d.im()) { - d.setMatrix(true, other_vec.nr(), other_vec.nc()); - } - } else { - std::size_t tempSize = other_vec.size(); - d.allocated = other_vec.d.allocated; - other_vec.d.sz = this->size(); - d.sz = tempSize; - T *tempP = other_vec.d.p; - other_vec.d.p = d.p; - d.p = tempP; - if (other_vec.d.im()) { - d.setMatrix(true, other_vec.nr(), other_vec.nc()); - } - } -} - -// NOTE: pointer constructor -Vec(T *ptr, std::size_t size) : d(size) { - if constexpr (isBorrow::value) { - d.init(ptr, size); - } else if constexpr (isBuffer::value) { - for (std::size_t i = 0; i < size; i++) - d[i] = ptr[i]; - d.setMatrix(false, 0, 0); - } -} -Vec(BaseType *ptr, std::size_t rows, std::size_t cols) : d(rows * cols) { - for (std::size_t i = 0; i < d.size(); i++) - d[i] = ptr[i]; - d.setMatrix(true, rows, cols); -} -#endif - -#endif diff --git a/inst/include/etr_bits/Vector/VectorClass.hpp b/inst/include/etr_bits/Vector/VectorClass.hpp index 7fdc0f3..01ade64 100644 --- a/inst/include/etr_bits/Vector/VectorClass.hpp +++ b/inst/include/etr_bits/Vector/VectorClass.hpp @@ -3,14 +3,6 @@ #include "../Core.hpp" -#include "../Allocation.hpp" -#include "../BinaryCalculations.hpp" - -#include "../SEXPConversions.hpp" -#include "../UnaryCalculations.hpp" - -#include "../Subsetting/LazySubsetting.hpp" - namespace etr { template struct Vec { @@ -22,25 +14,757 @@ template struct Vec { Buffer temp; using DType = R; using RetType = typename ReRef::type::RetType; - using typeTraitD = - typename ReRef::type::TypeTrait; - using isBuffer = typename std::is_same; - using isBorrow = typename std::is_same; - using isBorrowSEXP = typename std::is_same; - using isSubset = typename std::is_same; - using isSubsetClass = typename std::is_same; - using isVarPointer = typename std::is_same; - using caseTraitD = - typename ReRef::type::CaseTrait; - using isUnaryOP = typename std::is_same; - using isBinaryOP = typename std::is_same; - using isRVec = typename std::is_same; - using isVariableType = typename std::is_same; - - RetType getRetType() const { return RetType{}; } - -#include "AssignmentOperator.hpp" -#include "Constructors.hpp" + + + template Vec(T2 n) = delete; + +#ifdef DERIV_ETR + + // TODO: maybe for some constructors the deriv.allocated can be set to false + // instead of allocating + + // NOTE: define Vector with specific size + explicit Vec(SI &sz) : d(sz.sz), deriv(sz.sz) {} + explicit Vec(SI &&sz) : d(sz.sz), deriv(sz.sz) {} + + // NOTE: Buffer + template + explicit Vec(const Buffer &&inp) : d(inp), deriv(inp) { + d.setMatrix(inp.mp); + } + template + explicit Vec(const Buffer &inp) : d(inp), deriv(inp) { + d.setMatrix(inp.mp); + } + template + explicit Vec(const Buffer &inp) : d(inp), deriv(inp) { + d.setMatrix(inp.mp); + } + + // NOTE: Borrow + template + requires IS> + explicit Vec(const Borrow &&borrowed) : d(borrowed), deriv(borrowed.sz) { + d.setMatrix(borrowed.mp); + } + template + requires IS> + explicit Vec(const Borrow &borrowed) : d(borrowed), deriv(borrowed.sz) { + d.setMatrix(borrowed.mp); + } + template + requires IS> + explicit Vec(T *ptr, std::size_t s) : d(ptr, s), deriv(s) {} + + // NOTE: BorrowSEXP +#ifdef STANDALONE_ETR +#else + template + requires IS> + explicit Vec(SEXP &&inp) = delete; + + template + requires IS> + explicit Vec(SEXP inp) : d(inp) { + deriv.resize(d.sz); + deriv.fill(0.0); + } +#endif + + // NOTE: Subset + template + explicit Vec(const Subset &&inp) : d(inp), deriv(inp.size()) { + d.setMatrix(inp.mp); + } + template + explicit Vec(Subset &inp) : d(inp), deriv(inp.size()) { + d.setMatrix(inp.mp); + } + // NOTE: Subset lazy + template + requires IS + explicit Vec(const SubsetClass &&inp) + : d(inp), deriv(inp.size()) { + d.setMatrix(inp.mp); + } + template + requires IS + explicit Vec(SubsetClass &inp) : d(inp), deriv(inp.size()) { + d.setMatrix(inp.mp); + } + + // NOTE: Binary operation + template + requires IsBinaryOperation> + explicit Vec(const BinaryOperation &&inp) + : d(inp), deriv(inp.size()) { + using TypeTrait = OperationTrait; + d.setMatrix(inp.mp); + } + template // NOTE: only for comparison! + explicit Vec(const BinaryOperation &&inp) + : d(inp), deriv(inp.size()) { + using TypeTrait = OperationTrait; + d.setMatrix(inp.mp); + } + template + explicit Vec(BinaryOperation &inp) + : d(inp), deriv(inp.size()) { + using TypeTrait = OperationTrait; + d.setMatrix(inp.mp); + } + + // NOTE: Unary operation + template + explicit Vec(const UnaryOperation &&inp) + : d(inp), deriv(inp.size()) { + using TypeTrait = OperationTrait; + d.setMatrix(inp.mp); + } + template + explicit Vec(UnaryOperation &inp) + : d(inp), deriv(inp.size()) { + using TypeTrait = OperationTrait; + d.setMatrix(inp.mp); + } + + // NOTE: arithmetic constructors + explicit Vec(int sz) : d(1), deriv(1) { d[0] = static_cast(sz); } + explicit Vec(std::size_t sz) : d(1), deriv(1) { d[0] = sz; } + Vec(double sz) : d(1), deriv(1) { d[0] = sz; } +#ifdef STANDALONE_ETR + Vec(bool b) : d(1), deriv(1) { d[0] = static_cast(b); } +#else + // Vec(Rboolean b) : d(1), deriv(1) { d[0] = static_cast(b); } +#endif + + // NOTE: empty vector + explicit Vec() : d(), deriv() {} + + // NOTE: matrix constructors + explicit Vec(std::size_t rows, std::size_t cols) + : d(rows * cols), deriv(rows * cols) { + d.setMatrix(true, rows, cols); + } + explicit Vec(std::size_t rows, std::size_t cols, const double value) + : d(rows * cols), deriv(rows * cols) { + d.setMatrix(true, rows, cols); + d.fill(value); + } + // NOTE: other vector which is not of type RVec and has to be copied + template + requires IsVec> + Vec(const Vec &&other_vec) { + using TypeTrait = Trait2; + using CaseTrait = Trait2; + if constexpr (isBorrow::value) { + ass<"Sizes do not match">(d.sz <= + other_vec.size()); // FIX: is this correct? + d.sz = other_vec.size(); + for (std::size_t i = 0; i < d.size(); i++) { + d[i] = other_vec[i]; + } + if (other_vec.d.im()) { + d.setMatrix(true, other_vec.nr(), other_vec.nc()); + } + } else { + if (d.sz < other_vec.size()) { + this->d.resize(other_vec.size()); + } else { + d.sz = other_vec.size(); + } + for (std::size_t i = 0; i < d.size(); i++) { + d[i] = other_vec[i]; + } + if (other_vec.d.im()) { + d.setMatrix(true, other_vec.nr(), other_vec.nc()); + } + } + if (d.sz >= 1) { + deriv.resize(d.sz); + deriv.fill(1.0); + } + } + + // NOTE: other vector which is of type RVec and has different base type + template + requires(IsRVec> && !IS) + Vec(const Vec &&other_vec) { + using TypeTrait = Trait2; + using CaseTrait = Trait2; + if constexpr (isBorrow::value) { + ass<"Sizes do not match">(d.sz <= other_vec.size()); + d.sz = other_vec.size(); + for (std::size_t i = 0; i < d.size(); i++) { + d[i] = other_vec[i]; + } + if (other_vec.d.im()) { + d.setMatrix(true, other_vec.nr(), other_vec.nc()); + } + } else { + if (d.sz < other_vec.size()) { + this->d.resize(other_vec.size()); + } else { + d.sz = other_vec.size(); + } + for (std::size_t i = 0; i < d.size(); i++) { + d[i] = other_vec[i]; + } + if (other_vec.d.im()) { + d.setMatrix(true, other_vec.nr(), other_vec.nc()); + } + } + if (d.sz >= 1) { + deriv.resize(d.sz); + this->indep_var = other_vec.indep_var; + deriv.fill(0.0); + } + } + + // NOTE: other vector which is of type RVec and with same base type + template + requires(IsRVec> && IS) + Vec(Vec &&other_vec) { + using TypeTrait = Trait2; + using CaseTrait = Trait2; + if constexpr (isBorrow::value) { + ass<"Sizes do not match">(d.sz <= other_vec.size()); + d.sz = other_vec.size(); + for (std::size_t i = 0; i < d.size(); i++) { + d[i] = other_vec[i]; + } + if (other_vec.d.im()) { + d.setMatrix(true, other_vec.nr(), other_vec.nc()); + } + } else { + std::size_t tempSize = other_vec.size(); + d.allocated = other_vec.d.allocated; + other_vec.d.sz = this->size(); + d.sz = tempSize; + T *tempP = other_vec.d.p; + other_vec.d.p = d.p; + d.p = tempP; + if (other_vec.d.im()) { + d.setMatrix(true, other_vec.nr(), other_vec.nc()); + } + } + if (d.sz >= 1) { + deriv.resize(d.sz); + deriv.fill(0.0); + } + } + + // NOTE: pointer constructor + Vec(T *ptr, std::size_t size) : d(size), deriv(size) { + if constexpr (isBorrow::value) { + d.init(ptr, size); + } else if constexpr (isBuffer::value) { + for (std::size_t i = 0; i < size; i++) + d[i] = ptr[i]; + d.setMatrix(false, 0, 0); + } + deriv.fill(0.0); + } + Vec(BaseType *ptr, std::size_t rows, std::size_t cols) + : d(rows * cols), deriv(rows * cols) { + for (std::size_t i = 0; i < d.size(); i++) + d[i] = ptr[i]; + d.setMatrix(true, rows, cols); + deriv.fill(0.0); + } + +#else + // NOTE: define Vector with specific size + explicit Vec(SI &sz) : d(sz.sz) {} + explicit Vec(SI &&sz) : d(sz.sz) {} + + // NOTE: Buffer + template explicit Vec(const Buffer &&inp) : d(inp) { + d.setMatrix(inp.mp); + } + template explicit Vec(const Buffer &inp) : d(inp) { + d.setMatrix(inp.mp); + } + template + explicit Vec(const Buffer &inp) : d(inp) { + d.setMatrix(inp.mp); + } + + // NOTE: Borrow + template + requires IS> + explicit Vec(const Borrow &&borrowed) : d(borrowed) { + d.setMatrix(borrowed.mp); + } + template + requires IS> + explicit Vec(const Borrow &borrowed) : d(borrowed) { + d.setMatrix(borrowed.mp); + } + template + requires IS> + explicit Vec(T *ptr, std::size_t s) : d(ptr, s) {} + + // NOTE: BorrowSEXP +#ifdef STANDALONE_ETR +#else + template + requires IS> + explicit Vec(SEXP &&inp) = delete; + + template + requires IS> + explicit Vec(SEXP inp) : d(inp) {} +#endif + + // NOTE: Subset + template explicit Vec(const Subset &&inp) : d(inp) { + d.setMatrix(inp.mp); + } + template explicit Vec(Subset &inp) : d(inp) { + d.setMatrix(inp.mp); + } + // NOTE: Subset lazy + template + requires IS + explicit Vec(const SubsetClass &&inp) : d(std::move(inp)) { + d.setMatrix(inp.mp); + } + template + requires IS + explicit Vec(SubsetClass &inp) : d(std::move(inp)) { + d.setMatrix(inp.mp); + } + + // NOTE: Binary operation + template + explicit Vec(const BinaryOperation &&inp) : d(inp) { + d.setMatrix(inp.mp); + } + template + explicit Vec(BinaryOperation &inp) : d(inp) { + d.setMatrix(inp.mp); + } + + // NOTE: Unary operation + template + explicit Vec(const UnaryOperation &&inp) : d(inp) { + d.setMatrix(inp.mp); + } + template + explicit Vec(UnaryOperation &inp) : d(inp) { + d.setMatrix(inp.mp); + } + + // NOTE: arithmetic constructors + explicit Vec(int sz) : d(1) { d[0] = static_cast(sz); } + explicit Vec(std::size_t sz) : d(1) { d[0] = sz; } + Vec(double sz) : d(1) { d[0] = sz; } +#ifdef STANDALONE_ETR + Vec(bool b) : d(1) { d[0] = static_cast(b); } +#else + // Vec(Rboolean b) : d(1) { d[0] = static_cast(b); } +#endif + + // NOTE: empty vector + explicit Vec() : d() {} + + // NOTE: matrix constructors + explicit Vec(std::size_t rows, std::size_t cols) : d(rows * cols) { + d.setMatrix(true, rows, cols); + } + explicit Vec(std::size_t rows, std::size_t cols, const double value) + : d(rows * cols) { + d.setMatrix(true, rows, cols); + d.fill(value); + } + // NOTE: other vector which is not of type RVec and has to be copied + template + requires IsVec> + Vec(const Vec &&other_vec) { + if constexpr (IsBorrow) { + ass<"Sizes do not match">(d.sz <= + other_vec.size()); // FIX: is this correct? + d.sz = other_vec.size(); + for (std::size_t i = 0; i < d.size(); i++) { + d[i] = other_vec[i]; + } + if (other_vec.d.im()) { + d.setMatrix(true, other_vec.nr(), other_vec.nc()); + } + } else { + if (d.sz < other_vec.size()) { + this->d.resize(other_vec.size()); + } else { + d.sz = other_vec.size(); + } + for (std::size_t i = 0; i < d.size(); i++) { + d[i] = other_vec[i]; + } + if (other_vec.d.im()) { + d.setMatrix(true, other_vec.nr(), other_vec.nc()); + } + } + } + + // NOTE: other vector which is of type RVec and has different base type + template + requires(IsRVec> && !IS) + Vec(const Vec &&other_vec) { + if constexpr (IsBorrow) { + ass<"Sizes do not match">(d.sz <= other_vec.size()); + d.sz = other_vec.size(); + for (std::size_t i = 0; i < d.size(); i++) { + d[i] = other_vec[i]; + } + if (other_vec.d.im()) { + d.setMatrix(true, other_vec.nr(), other_vec.nc()); + } + } else { + if (d.sz < other_vec.size()) { + this->d.resize(other_vec.size()); + } else { + d.sz = other_vec.size(); + } + for (std::size_t i = 0; i < d.size(); i++) { + d[i] = other_vec[i]; + } + if (other_vec.d.im()) { + d.setMatrix(true, other_vec.nr(), other_vec.nc()); + } + } + } + + // NOTE: other vector which is of type RVec and with same base type + template + requires(IsRVec> && IS) + Vec(Vec &&other_vec) { + if constexpr (IsBorrow) { + ass<"Sizes do not match">(d.sz <= other_vec.size()); + d.sz = other_vec.size(); + for (std::size_t i = 0; i < d.size(); i++) { + d[i] = other_vec[i]; + } + if (other_vec.d.im()) { + d.setMatrix(true, other_vec.nr(), other_vec.nc()); + } + } else { + std::size_t tempSize = other_vec.size(); + d.allocated = other_vec.d.allocated; + other_vec.d.sz = this->size(); + d.sz = tempSize; + T *tempP = other_vec.d.p; + other_vec.d.p = d.p; + d.p = tempP; + if (other_vec.d.im()) { + d.setMatrix(true, other_vec.nr(), other_vec.nc()); + } + } + } + + // NOTE: pointer constructor + Vec(T *ptr, std::size_t size) : d(size) { + if constexpr (IsBorrow) { + d.init(ptr, size); + } else if constexpr (IsLBuffer) { + for (std::size_t i = 0; i < size; i++) + d[i] = ptr[i]; + d.setMatrix(false, 0, 0); + } + } + Vec(BaseType *ptr, std::size_t rows, std::size_t cols) : d(rows * cols) { + for (std::size_t i = 0; i < d.size(); i++) + d[i] = ptr[i]; + d.setMatrix(true, rows, cols); + } +#endif + + +// Assignments +template + requires IsArithV +Vec &operator=(const TD inp) { + static_assert(!IsUnary, "Cannot assign to unary calculation"); + static_assert(!IsBinary, "Cannot assign to binary calculation"); + static_assert(!IsRBuffer, + "Cannot assign to an r value. E.g. c(1, 2, 3) <- 1"); + if constexpr (is) { + if constexpr (IsSubset) { + for (std::size_t i = 0; i < d.ind.size(); i++) { + d[i] = inp; + } +#ifdef DERIV_ETR + for (std::size_t i = 0; i < d.ind.size(); i++) { + deriv[i] = 0; + } +#endif + } else if constexpr (IsBorrow) { + d.sz = 1; + d[0] = inp; +#ifdef DERIV_ETR + deriv.resize(1); + deriv[0] = 0; +#endif + + } else { + d.resize(1); + d[0] = inp; +#ifdef DERIV_ETR + deriv.resize(1); + deriv[0] = 0; +#endif + } + return *this; + } else { + if constexpr (IsSubset) { + for (std::size_t i = 0; i < d.ind.size(); i++) { + d[i] = static_cast(inp); + } +#ifdef DERIV_ETR + for (std::size_t i = 0; i < d.ind.size(); i++) { + deriv[i] = 0; + } +#endif + + } else if constexpr (IsBorrow) { + d.sz = 1; + d[0] = static_cast(inp); +#ifdef DERIV_ETR + deriv.resize(1); + deriv[0] = 0; +#endif + + } else { + d.resize(1); + d[0] = static_cast(inp); +#ifdef DERIV_ETR + deriv.resize(1); + deriv[0] = 0; +#endif + } + return *this; + } +} + +Vec &operator=(const Vec &otherVec) { + static_assert(!IsUnary, "Cannot assign to unary calculation"); + static_assert(!IsBinary, "Cannot assign to binary calculation"); + static_assert(!IsRBuffer, + "Cannot assign to an r value. E.g. c(1, 2, 3) <- 1"); + + using DataTypeOtherVec = typename etr::ExtractDataType< + ReRef>::RetType; + if constexpr (IsLBuffer) { + temp.resize(otherVec.size()); + for (std::size_t i = 0; i < otherVec.size(); i++) { + if constexpr (is) { + temp[i] = otherVec[i]; + } else { + temp[i] = static_cast(otherVec[i]); + } + } + d.moveit(temp); + } else if constexpr (IsBorrow) { + ass<"number of items to replace is not a multiple of replacement length">( + otherVec.size() <= d.capacity); + temp.resize(otherVec.size()); + for (std::size_t i = 0; i < otherVec.size(); i++) { + if constexpr (is) { + temp[i] = otherVec[i]; + } else { + temp[i] = static_cast(otherVec[i]); + } + } + ass<"size cannot be increased above the size of the borrowed object">( + d.sz <= otherVec.size()); + d.sz = otherVec.size(); + for (std::size_t i = 0; i < otherVec.size(); i++) + d[i] = temp[i]; + } else if constexpr (IsBorrowSEXP) { + temp.resize(otherVec.size()); + for (std::size_t i = 0; i < otherVec.size(); i++) { + if constexpr (is) { + temp[i] = otherVec[i]; + } else { + temp[i] = static_cast(otherVec[i]); + } + } + if (otherVec.size() > this->size()) + d.resize(otherVec.size()); + + for (std::size_t i = 0; i < otherVec.size(); i++) + d[i] = temp[i]; + + } else if constexpr (IsSubset) { + ass<"number of items to replace is not a multiple of replacement length">( + otherVec.size() == d.ind.size()); + temp.resize(otherVec.size()); + for (std::size_t i = 0; i < otherVec.size(); i++) { + if constexpr (is) { + temp[i] = otherVec[i]; + } else { + temp[i] = static_cast(otherVec[i]); + } + } + if (d.p->size() < temp.size()) + d.resize(temp.size()); + for (std::size_t i = 0; i < d.ind.size(); i++) { + d[i % d.ind.size()] = temp[i]; + } + } + if (otherVec.d.im()) { + d.setMatrix(true, otherVec.d.nr(), otherVec.d.nc()); + } + +#ifdef DERIV_ETR + // TODO: what if other Vec is subsetted + // deriv.resize(otherVec.size()); + // for (std::size_t i = 0; i < deriv.size(); i++) { + // deriv[i] = otherVec.deriv[i]; + // } + // TODO: is there something to do here? +#endif + + return *this; +} + +// TODO: finish this +template + requires(IsRVec> && IS) +Vec &operator=(Vec &&otherVec) { + static_assert(!IsUnary, "Cannot assign to unary calculation"); + static_assert(!IsBinary, "Cannot assign to binary calculation"); + static_assert(!IsRBuffer, + "Cannot assign to an r value. E.g. c(1, 2, 3) <- 1"); + std::size_t tempSize = otherVec.size(); + std::size_t tempCapacity = otherVec.d.capacity; + T *tempP = otherVec.d.p; + bool allocated = otherVec.d.allocated; + + otherVec.d.allocated = d.allocated; + otherVec.d.sz = this->size(); + otherVec.d.capacity = d.capacity; + otherVec.d.p = d.p; + + d.allocated = allocated; + d.sz = tempSize; + d.capacity = tempCapacity; + d.p = tempP; + + if (otherVec.d.im()) { + d.setMatrix(true, otherVec.nr(), otherVec.nc()); + } +#ifdef DERIV_ETR + deriv.resize(this->size()); + for (std::size_t i = 0; i < deriv.size(); i++) { + deriv[i] = 0; + } +#endif + + return *this; +} + +template +Vec &operator=(const Vec &otherVec) { + static_assert(!IsUnary, "Cannot assign to unary calculation"); + static_assert(!IsBinary, "Cannot assign to binary calculation"); + static_assert(!IsRBuffer, + "Cannot assign to an r value. E.g. c(1, 2, 3) <- 1"); + // TODO: replace is with IS + using DataTypeOtherVec = typename ReRef::type::RetType; + if constexpr (IsLBuffer) { + + temp.resize(otherVec.size()); + for (std::size_t i = 0; i < otherVec.size(); i++) { + if constexpr (is) { + temp[i] = otherVec[i]; + } else { + temp[i] = static_cast(otherVec[i]); + } + } + d.moveit(temp); + } else if constexpr (IsBorrow) { + ass<"number of items to replace is not a multiple of replacement length">( + otherVec.size() <= d.capacity); + temp.resize(otherVec.size()); + for (std::size_t i = 0; i < otherVec.size(); i++) { + if constexpr (is) { + temp[i] = otherVec[i]; + } else { + temp[i] = static_cast(otherVec[i]); + } + } + ass<"size cannot be increased above the size of the borrowed object">( + d.sz <= otherVec.size()); + d.sz = otherVec.size(); + for (std::size_t i = 0; i < otherVec.size(); i++) + d[i] = temp[i]; + } else if constexpr (IsBorrowSEXP) { + temp.resize(otherVec.size()); + for (std::size_t i = 0; i < otherVec.size(); i++) { + if constexpr (is) { + temp[i] = otherVec[i]; + } else { + temp[i] = static_cast(otherVec[i]); + } + } + if (otherVec.size() > this->size()) + d.resize(otherVec.size()); + + for (std::size_t i = 0; i < otherVec.size(); i++) + d[i] = temp[i]; + + } else if constexpr (IsSubset) { + ass<"number of items to replace is not a multiple of replacement length">( + otherVec.size() == d.ind.size()); + temp.resize(otherVec.size()); + for (std::size_t i = 0; i < otherVec.size(); i++) { + if constexpr (is) { + temp[i] = otherVec[i]; + } else { + temp[i] = static_cast(otherVec[i]); + } + } + for (std::size_t i = 0; i < d.ind.size(); i++) { + d[i % d.ind.size()] = temp[i]; + } + } + if (otherVec.d.im()) { + d.setMatrix(true, otherVec.d.nr(), otherVec.d.nc()); + } + +#ifdef DERIV_ETR + if constexpr (IsRVec> || + Operation) { + deriv.resize(this->size()); + // for (std::size_t i = 0; i < deriv.size(); i++) { + // deriv[i] = 0; + // } + } else { + // deriv.resize(otherVec.size()); + // for (std::size_t i = 0; i < deriv.sz; i++) { + // deriv[i] = otherVec.deriv[i]; + // } + } +#endif + + return *this; +} + +#ifdef STANDALONE_ETR +#else +Vec &operator=(SEXP s) { + d.initSEXP(s); +#ifdef DERIV_ETR + deriv.resize(d.sz); + deriv.fill(0.0); +#endif + return *this; +} +#endif + + RetType &operator[](std::size_t idx) { return d[idx]; } RetType operator[](std::size_t idx) const { return d[idx]; } @@ -64,18 +788,18 @@ template struct Vec { std::size_t nr() const { return d.nr(); } auto begin() const { - if constexpr (isSubset::value) { + if constexpr (IsSubset) { return It{d.p->p}; - } else if constexpr (isSubsetClass::value) { + } else if constexpr (IsSubsetClass) { return d.begin(); } else { return It{d.p}; } } auto end() const { - if constexpr (isSubset::value) { + if constexpr (IsSubset) { return It{d.p->p + this->size()}; - } else if constexpr (isSubsetClass::value) { + } else if constexpr (IsSubsetClass) { return d.end(); } else { return It{d.p + this->size()}; @@ -190,14 +914,6 @@ template struct Vec { } #endif - template auto operator()(const I &idx) { - return subset(*this, idx); - } - - template - auto operator()(const IL &idxL, const IR &idxR) { - return subset(*this, idxL, idxR); - } }; } // namespace etr