diff --git a/.development/test_subsetting.cpp b/.development/test_subsetting.cpp index e5003b4..209db08 100644 --- a/.development/test_subsetting.cpp +++ b/.development/test_subsetting.cpp @@ -1,372 +1,25 @@ #define STANDALONE_ETR -#include "../inst/include/etr_bits/Core.hpp" -#include "../inst/include/etr_bits/Subsetting/LazySubsetting.hpp" -#include "../inst/include/etr_bits/BufferVector.hpp" +#include "../inst/include/etr_bits/Allocation.hpp" #include "../inst/include/etr_bits/BinaryCalculations.hpp" -#include "../inst/include/etr_bits/UnaryCalculations.hpp" +#include "../inst/include/etr_bits/BufferVector.hpp" #include "../inst/include/etr_bits/Coca.hpp" +#include "../inst/include/etr_bits/Core.hpp" #include "../inst/include/etr_bits/Printing.hpp" -#include "../inst/include/etr_bits/Allocation.hpp" +#include "../inst/include/etr_bits/Subsetting/LazySubsetting.hpp" +#include "../inst/include/etr_bits/UnaryCalculations.hpp" using namespace etr; -void test_subsetting_l_vector() { +int main() { Vec a; - Vec b; - Vec c; - Vec d; - Vec e; a = coca(1, 2, 3, 4); - - { - std::cout << "Test subsetting L Vec with bool value" << std::endl; - c = subset_test(a, true); - ass<"Size should be 4">(c.size() == 4); - try { - c = subset_test(a, false); - } catch(std::exception& e) { - std::string expected = "Size has to be larger than 0!"; - ass<"Using false should throw an error">(e.what() == expected); - } - } - { - std::cout << "Test subsetting L Vec with integers" << std::endl; - c = subset_test(a, 1); - ass<"Size should be 1">(c.size() == 1); - ass<"c value should be 1">(c.d[0] == 1); - c = subset_test(a, 4); - ass<"Size should be 1">(c.size() == 1); - ass<"c value should be 4">(c.d[0] == 4); - try { - c = subset_test(a, 0); - } catch(std::exception& e) { - std::string expected = "Error: out of boundaries"; - ass<"Index == 0">(e.what() == expected); - } - try { - c = subset_test(a, -1); - } catch(std::exception& e) { - std::string expected = "Negative indices are not supported"; - ass<"Negative indices are not supported">(e.what() == expected); - } - try { - c = subset_test(a, 100); - } catch(std::exception& e) { - std::string expected = "Error: out of boundaries"; - ass<"Indices > size">(e.what() == expected); - } - } - { - std::cout << "Test subsetting L Vec with doubles" << std::endl; - c = subset_test(a, 1.1); - ass<"Size should be 1">(c.size() == 1); - ass<"c value should be 1">(c.d[0] == 1); - c = subset_test(a, 4.2); - ass<"Size should be 1">(c.size() == 1); - ass<"c value should be 4">(c.d[0] == 4); - try { - c = subset_test(a, 0.000); - } catch(std::exception& e) { - std::string expected = "Error: out of boundaries"; - ass<"Index == 0">(e.what() == expected); - } - try { - c = subset_test(a, -4.5); - } catch(std::exception& e) { - std::string expected = "Negative indices are not supported"; - ass<"Negative indices are not supported">(e.what() == expected); - } - try { - c = subset_test(a, 100.3); - } catch(std::exception& e) { - std::string expected = "Error: out of boundaries"; - ass<"Indices > size">(e.what() == expected); - } - } - { - b = coca(1, 2, 1, 4, 1, 2); - std::cout << "Test subsetting L Vec with integer Vector" << std::endl; - c = subset_test(a, b); - ass<"Size should be 6">(c.size() == 6); - ass<"c[0] == 1">(c.d[0] == 1); - ass<"c[4] == 1">(c.d[4] == 1); - try { - b = coca(-1, -2, 3, 4); - c = subset_test(a, b); - } catch(std::exception& e) { - std::string expected = "Error: out of boundaries"; - ass<"Invalid indices">(e.what() == expected); - } - try { - b = coca(100); - c = subset_test(a, b); - } catch(std::exception& e) { - std::string expected = "Error: out of boundaries"; - ass<"Invalid indices">(e.what() == expected); - } - } - { - d = coca(1.0, 2.0, 1.0, 4.0, 1.0, 2.0); - std::cout << "Test subsetting L Vec with double Vector" << std::endl; - c = subset_test(a, d); - ass<"Size should be 6">(c.size() == 6); - ass<"c[0] == 1">(c.d[0] == 1); - ass<"c[4] == 1">(c.d[4] == 1); - try { - d = coca(-1.0, -2.0, 3.0, 4.0); - c = subset_test(a, d); - } catch(std::exception& e) { - std::string expected = "Error: out of boundaries"; - ass<"Invalid indices">(e.what() == expected); - } - try { - d = coca(100.0); - c = subset_test(a, d); - } catch(std::exception& e) { - std::string expected = "Error: out of boundaries"; - ass<"Invalid indices">(e.what() == expected); - } - try { - d = vector_numeric(0); - c = subset_test(a, d); - } catch(std::exception& e) { - std::string expected = "invalid times argument"; // TODO: better error message - ass<"Invalid indices">(e.what() == expected); - } - } - { - a = coca(1, 2, 3, 5, 6, 7); - b = coca(1, 4); - std::cout << "Test subsetting L Vec with another Subset" << std::endl; - c = subset_test(a, subset_test(a, b)); - ass<"Size should be 2">(c.size() == 2); - ass<"c[0] == 1">(c.d[0] == 1); - ass<"c[1] == 1">(c.d[1] == 6); - } - { - std::cout << "Test subsetting L Vec with bool Vector" << std::endl; - a = coca(1, 2, 3, 4); - e = coca(true, false, true); - c = subset_test(a, e); - ass<"Size should be 3">(c.size() == 3); - ass<"c[0] == 1">(c.d[0] == 1); - ass<"c[1] == 3">(c.d[1] == 3); - ass<"c[2] == 4">(c.d[2] == 4); - - a = coca(1, 2, 3, 4); - e = coca(false, false, false); - try{ - c = subset_test(a, e); - } catch (std::exception& e) { - std::string expected = "Size has to be larger than 0!!!"; - ass<"Invalid size argument">(e.what() == expected); - } - - a = coca(1, 2, 3, 4); - e = coca(true, true, false, true, true); - c = subset_test(a, e); - ass<"Size should be 4">(c.size() == 3); - ass<"c[0] == 1">(c.d[0] == 1); - ass<"c[1] == 2">(c.d[1] == 2); - ass<"c[2] == 4">(c.d[2] == 4); - } - -} - -void test_subsetting_r_vector() { - Vec b; - Vec c; - Vec d; - Vec e; - - { - std::cout << "Test subsetting R Vec with bool value" << std::endl; - c = subset_test(coca(1, 2, 3, 4), true); - ass<"Size should be 4">(c.size() == 4); - try { - c = subset_test(coca(1, 2, 3, 4), false); - } catch(std::exception& e) { - std::string expected = "Size has to be larger than 0!"; - ass<"Using false should throw an error">(e.what() == expected); - } - } - { - std::cout << "Test subsetting R Vec with integers" << std::endl; - c = subset_test(coca(1, 2, 3, 4), 1); - ass<"Size should be 1">(c.size() == 1); - ass<"c value should be 1">(c.d[0] == 1); - c = subset_test(coca(1, 2, 3, 4), 4); - ass<"Size should be 1">(c.size() == 1); - ass<"c value should be 4">(c.d[0] == 4); - try { - c = subset_test(coca(1, 2, 3, 4), 0); - } catch(std::exception& e) { - std::string expected = "Error: out of boundaries"; - ass<"Index == 0">(e.what() == expected); - } - try { - c = subset_test(coca(1, 2, 3, 4), -1); - } catch(std::exception& e) { - std::string expected = "Negative indices are not supported"; - ass<"Negative indices are not supported">(e.what() == expected); - } - try { - c = subset_test(coca(1, 2, 3, 4), 100); - } catch(std::exception& e) { - std::string expected = "Error: out of boundaries"; - ass<"Indices > size">(e.what() == expected); - } - } - { - std::cout << "Test subsetting R Vec with doubles" << std::endl; - c = subset_test(coca(1, 2, 3, 4), 1.1); - ass<"Size should be 1">(c.size() == 1); - ass<"c value should be 1">(c.d[0] == 1); - c = subset_test(coca(1, 2, 3, 4), 4.2); - ass<"Size should be 1">(c.size() == 1); - ass<"c value should be 4">(c.d[0] == 4); - try { - c = subset_test(coca(1, 2, 3, 4), 0.000); - } catch(std::exception& e) { - std::string expected = "Error: out of boundaries"; - ass<"Index == 0">(e.what() == expected); - } - try { - c = subset_test(coca(1, 2, 3, 4), -4.5); - } catch(std::exception& e) { - std::string expected = "Negative indices are not supported"; - ass<"Negative indices are not supported">(e.what() == expected); - } - try { - c = subset_test(coca(1, 2, 3, 4), 100.3); - } catch(std::exception& e) { - std::string expected = "Error: out of boundaries"; - ass<"Indices > size">(e.what() == expected); - } - } - { - b = coca(1, 2, 1, 4, 1, 2); - std::cout << "Test subsetting R Vec with integer Vector" << std::endl; - c = subset_test(coca(1, 2, 3, 4), b); - ass<"Size should be 6">(c.size() == 6); - ass<"c[0] == 1">(c.d[0] == 1); - ass<"c[4] == 1">(c.d[4] == 1); - try { - b = coca(-1, -2, 3, 4); - c = subset_test(coca(1, 2, 3, 4), b); - } catch(std::exception& e) { - std::string expected = "Error: out of boundaries"; - ass<"Invalid indices">(e.what() == expected); - } - try { - b = coca(100); - c = subset_test(coca(1, 2, 3, 4), b); - } catch(std::exception& e) { - std::string expected = "Error: out of boundaries"; - ass<"Invalid indices">(e.what() == expected); - } - } - { - d = coca(1.0, 2.0, 1.0, 4.0, 1.0, 2.0); - std::cout << "Test subsetting R Vec with double Vector" << std::endl; - c = subset_test(coca(1, 2, 3, 4), d); - ass<"Size should be 6">(c.size() == 6); - ass<"c[0] == 1">(c.d[0] == 1); - ass<"c[4] == 1">(c.d[4] == 1); - try { - d = coca(-1.0, -2.0, 3.0, 4.0); - c = subset_test(coca(1, 2, 3, 4), d); - } catch(std::exception& e) { - std::string expected = "Error: out of boundaries"; - ass<"Invalid indices">(e.what() == expected); - } - try { - d = coca(100.0); - c = subset_test(coca(1, 2, 3, 4), d); - } catch(std::exception& e) { - std::string expected = "Error: out of boundaries"; - ass<"Invalid indices">(e.what() == expected); - } - try { - d = vector_numeric(0); - c = subset_test(coca(1, 2, 3, 4), d); - } catch(std::exception& e) { - std::string expected = "invalid times argument"; // TODO: better error message - ass<"Invalid indices">(e.what() == expected); - } - } - { - b = coca(1, 4); - std::cout << "Test subsetting R Vec with another Subset" << std::endl; - c = subset_test(coca(1, 2, 3, 5, 6, 7), subset_test(coca(1,2,3, 5, 6, 7), b)); - ass<"Size should be 2">(c.size() == 2); - ass<"c[0] == 1">(c.d[0] == 1); - ass<"c[1] == 1">(c.d[1] == 6); - } - { - std::cout << "Test subsetting R Vec with bool Vector" << std::endl; - e = coca(true, false, true); - c = subset_test(coca(1, 2, 3, 4), e); - ass<"Size should be 3">(c.size() == 3); - ass<"c[0] == 1">(c.d[0] == 1); - ass<"c[1] == 3">(c.d[1] == 3); - ass<"c[2] == 4">(c.d[2] == 4); - - e = coca(false, false, false); - try{ - c = subset_test(coca(1, 2, 3, 4), e); - } catch (std::exception& e) { - std::string expected = "Size has to be larger than 0!!!"; - ass<"Invalid size argument">(e.what() == expected); - } - - e = coca(true, true, false, true, true); - c = subset_test(coca(1, 2, 3, 4), e); - ass<"Size should be 4">(c.size() == 3); - ass<"c[0] == 1">(c.d[0] == 1); - ass<"c[1] == 2">(c.d[1] == 2); - ass<"c[2] == 4">(c.d[2] == 4); - } - -} - - -void test_subsetting_with_r_val() { - Vec a; - Vec b; - Vec c; - Vec d; - Vec e; - { - // b = coca(1, 2, 1, 4, 1, 2); - // std::cout << "Test subsetting Vec with calculation" << std::endl; - // c = subset_test(coca(1, 2, 3, 4), b * 1.1); - // ass<"Size should be 6">(c.size() == 6); - // ass<"c[0] == 1">(c.d[0] == 1); - // ass<"c[4] == 1">(c.d[4] == 1); - // - // a = coca(1, 2, 3, 4); - // b = coca(1, 2, 1, 4, 1, 2); - // c = subset_test(a, b * 1.1); - // ass<"Size should be 6">(c.size() == 6); - // ass<"c[0] == 1">(c.d[0] == 1); - // ass<"c[4] == 1">(c.d[4] == 1); - // - a = coca(4, 5, 6, 7); - b = coca(1, 2, 1, 4, 1, 2); - c = 1; - auto test2 = subset_test(a, subset_test(coca(1.1, 2.2, 3.3), coca(1, 3))); - printTAST(); - std::cout << test2.size() << std::endl; - std::cout << test2.d.size() << std::endl; - std::cout << test2.d.l.size() << std::endl; - std::cout << test2.d.r.size() << std::endl; - print(test2.d.l); - // c = subset_test(a, subset_test(coca(1.1, 2.2, 3.3), coca(1, 3))); - } -} - -int main() { - // test_subsetting_l_vector(); - // test_subsetting_r_vector(); - test_subsetting_with_r_val(); + std::cout << "Start" << std::endl; + // print(a); + // sub[0] = 3.14; + // print(a); + // subset_test(a, 2) = 40; + // print(a); + // subset_test(a, true) = 3.1; + // print(a); + subset_test(a, coca(1, 3)) = coca(10, 20); + // print(a); } diff --git a/inst/include/etr_bits/BinaryCalculations.hpp b/inst/include/etr_bits/BinaryCalculations.hpp index 2e311ae..4a530c9 100644 --- a/inst/include/etr_bits/BinaryCalculations.hpp +++ b/inst/include/etr_bits/BinaryCalculations.hpp @@ -9,9 +9,9 @@ template struct BinaryOpClassIterator { const L &l; const R &r; size_t index; - + BinaryOpClassIterator(const L &l, const R &r, size_t index = 0) - : l(l), r(r), index(index) {} + : l(l), r(r), index(index) {} auto operator*() const { if constexpr (!IsArithV && IsArithV) { @@ -33,24 +33,24 @@ template struct BinaryOpClassIterator { } }; -template +template inline auto determine_type_binary_op() { if constexpr (IsComparison) { return bool{}; - } else if constexpr (IsClassV &&IsClassV) { - using RetType = std::common_type_t; + } else if constexpr (IsClassV && IsClassV) { + using RetType = + std::common_type_t; return RetType{}; - } else if constexpr(!IsClassV &&IsClassV) { + } else if constexpr (!IsClassV && IsClassV) { using RetType = std::common_type_t; return RetType{}; - } else if constexpr(IsClassV && !IsClassV) { + } else if constexpr (IsClassV && !IsClassV) { using RetType = std::common_type_t; return RetType{}; } } -template -struct BinaryOperation { +template struct BinaryOperation { using Trait = BTrait; using RetType = decltype(determine_type_binary_op()); const L &l; @@ -136,79 +136,93 @@ struct BinaryOperation { } auto begin() const { return BinaryOpClassIterator{l, r, 0}; } - auto end() const { return BinaryOpClassIterator{l, r, this->size()}; } - + auto end() const { + return BinaryOpClassIterator{l, r, this->size()}; + } }; template using BinaryOpResult = decltype(determine_type_binary_op()); template -using BinaryVec = Vec, BinaryOperation>; +using BinaryVec = + Vec, BinaryOperation>; template inline auto create_bin_vec(const L &l, const R &r) { if constexpr (!IsArithV && IsArithV) { - return BinaryVec( + return BinaryVec( BinaryOperation(l.d, r)); } else if constexpr (IsArithV && !IsArithV) { - return BinaryVec( + return BinaryVec( BinaryOperation(l, r.d)); } else if constexpr (!IsArithV && !IsArithV) { - return BinaryVec( + return BinaryVec( BinaryOperation(l.d, r.d)); } else { ass<"This case should not be reached. Contact author">(false); } } -// TODO: does this work with R values? If not use either approach as in LazySubsetting or change to const L& +// TODO: does this work with R values? If not use either approach as in +// LazySubsetting or change to const L& template auto operator+(L &&l, R &&r) { - return create_bin_vec, std::decay_t, PlusTrait>(std::forward(l), std::forward(r)); + return create_bin_vec, std::decay_t, PlusTrait>( + std::forward(l), std::forward(r)); } template auto operator-(L &&l, R &&r) { - return create_bin_vec, std::decay_t, MinusTrait>(std::forward(l), std::forward(r)); + return create_bin_vec, std::decay_t, MinusTrait>( + std::forward(l), std::forward(r)); } template auto operator*(L &&l, R &&r) { - return create_bin_vec, std::decay_t, TimesTrait>(std::forward(l), std::forward(r)); + return create_bin_vec, std::decay_t, TimesTrait>( + std::forward(l), std::forward(r)); } template auto operator/(L &&l, R &&r) { - return create_bin_vec, std::decay_t, DivideTrait>(std::forward(l), std::forward(r)); + return create_bin_vec, std::decay_t, DivideTrait>( + std::forward(l), std::forward(r)); } template auto power(L &&l, R &&r) { - return create_bin_vec, std::decay_t, PowTrait>(std::forward(l), std::forward(r)); + return create_bin_vec, std::decay_t, PowTrait>( + std::forward(l), std::forward(r)); } -template -requires (IsVec || IsVec) +template + requires(IsVec || IsVec) auto operator==(L &&l, R &&r) { - return create_bin_vec, std::decay_t, EqualTrait>(std::forward(l), std::forward(r)); + return create_bin_vec, std::decay_t, EqualTrait>( + std::forward(l), std::forward(r)); } template -requires (IsVec || IsVec) + requires(IsVec || IsVec) auto operator!=(L &&l, R &&r) { - return create_bin_vec, std::decay_t, UnEqualTrait>(std::forward(l), std::forward(r)); + return create_bin_vec, std::decay_t, UnEqualTrait>( + std::forward(l), std::forward(r)); } template auto operator>(L &&l, R &&r) { - return create_bin_vec, std::decay_t, LargerTrait>(std::forward(l), std::forward(r)); + return create_bin_vec, std::decay_t, LargerTrait>( + std::forward(l), std::forward(r)); } template auto operator>=(L &&l, R &&r) { - return create_bin_vec, std::decay_t, LargerEqualTrait>(std::forward(l), std::forward(r)); + return create_bin_vec, std::decay_t, LargerEqualTrait>( + std::forward(l), std::forward(r)); } template auto operator<(L &&l, R &&r) { - return create_bin_vec, std::decay_t, SmallerTrait>(std::forward(l), std::forward(r)); + return create_bin_vec, std::decay_t, SmallerTrait>( + std::forward(l), std::forward(r)); } template auto operator<=(L &&l, R &&r) { - return create_bin_vec, std::decay_t, SmallerEqualTrait>(std::forward(l), std::forward(r)); + return create_bin_vec, std::decay_t, SmallerEqualTrait>( + std::forward(l), std::forward(r)); } } // namespace etr diff --git a/inst/include/etr_bits/Core/BaseStore.hpp b/inst/include/etr_bits/Core/BaseStore.hpp index aeaa198..9c1ca59 100644 --- a/inst/include/etr_bits/Core/BaseStore.hpp +++ b/inst/include/etr_bits/Core/BaseStore.hpp @@ -33,7 +33,7 @@ template struct BaseStore { } // constructors - BaseStore(const BaseStore &other) + BaseStore(const BaseStore &other) : sz(other.sz), capacity(other.capacity), allocated(other.allocated) { if (other.allocated) { p = new T[capacity]; @@ -42,14 +42,11 @@ template struct BaseStore { p = nullptr; } } - BaseStore(BaseStore &&other) noexcept - : sz(other.sz), capacity(other.capacity), allocated(other.allocated), - p(other.p) { - other.capacity = 0; - other.sz = 0; - other.allocated = false; - other.p = nullptr; - } + BaseStore(BaseStore &&other) noexcept + : p(std::exchange(other.p, nullptr)), sz(std::exchange(other.sz, 0)), + capacity(std::exchange(other.capacity, 0)), + allocated(std::exchange(other.allocated, false)), + mp(std::move(other.mp)) {} #ifdef STANDALONE_ETR #else BaseStore(SEXP s) { @@ -101,7 +98,8 @@ template struct BaseStore { }; #endif BaseStore(std::size_t sz_) - : sz(sz_), capacity(static_cast(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++) { @@ -138,6 +136,17 @@ template struct BaseStore { } return *this; } + BaseStore &operator=(BaseStore &&other) noexcept { + if (this != &other) { + delete[] p; + p = std::exchange(other.p, nullptr); + sz = std::exchange(other.sz, 0); + capacity = std::exchange(other.capacity, 0); + allocated = std::exchange(other.allocated, false); + mp = std::move(other.mp); + } + return *this; + } template requires(IsArithV) @@ -150,8 +159,8 @@ template struct BaseStore { } } - template -requires (!IsArithV) + template + requires(!IsArithV) void fill(TInp &&inp) { ass<"cannot use fill with vectors of different lengths">(inp.size() == sz); using DataType = typename ReRef::type::RetType; @@ -266,7 +275,8 @@ requires (!IsArithV) if (newSize > capacity) { ass<"try to delete nullptr">(p != nullptr); delete[] p; - capacity = static_cast(static_cast(newSize) * 1.15); + capacity = + static_cast(static_cast(newSize) * 1.15); p = new T[capacity]; sz = newSize; allocated = true; diff --git a/inst/include/etr_bits/Core/Concepts.hpp b/inst/include/etr_bits/Core/Concepts.hpp index 6bb2539..b14b549 100644 --- a/inst/include/etr_bits/Core/Concepts.hpp +++ b/inst/include/etr_bits/Core/Concepts.hpp @@ -11,89 +11,88 @@ template struct AddConst { namespace etr { template -concept isBID = requires { - requires IS || IS || - IS; -}; +concept isBID = + requires { requires IS || IS || IS; }; // Test R class // =================================================================== +// TODO: Test whether these really work +// SubsetClassTrait didn't work in one test template concept IsSubset = requires { - typename ReRef::type::Trait; - requires IS::type::Trait, SubsetTrait>; + typename ReRef::type::Trait; + requires IS::type::Trait, SubsetTrait>; }; template concept IsSubsetClass = requires { - typename ReRef::type::Trait; - requires IS::type::Trait, SubsetClassTrait>; + typename ReRef::type::Trait; + requires IS::type::Trait, SubsetClassTrait>; }; template concept IsLBuffer = requires { - typename ReRef::type::Trait; - requires IS::type::Trait, LBufferTrait>; + typename ReRef::type::Trait; + requires IS::type::Trait, LBufferTrait>; }; template concept IsRBuffer = requires { - typename ReRef::type::Trait; - requires IS::type::Trait, RBufferTrait>; + typename ReRef::type::Trait; + requires IS::type::Trait, RBufferTrait>; }; template concept IsBorrow = requires { - typename ReRef::type::Trait; - requires IS::type::Trait, BorrowTrait>; + typename ReRef::type::Trait; + requires IS::type::Trait, BorrowTrait>; }; template concept IsBorrowSEXP = requires { - typename ReRef::type::Trait; - requires IS::type::Trait, BorrowSEXPTrait>; + typename ReRef::type::Trait; + requires IS::type::Trait, BorrowSEXPTrait>; }; template concept IsUnary = requires { - typename ReRef::type::Trait; - requires IS::type::Trait, SinusTrait> || - IS::type::Trait, ASinusTrait> || - IS::type::Trait, SinusHTrait> || - IS::type::Trait, CosinusTrait> || - IS::type::Trait, ACosinusTrait> || - IS::type::Trait, CosinusHTrait> || - IS::type::Trait, TangensTrait> || - IS::type::Trait, ATangensTrait> || - IS::type::Trait, TangensHTrait> || - IS::type::Trait, ExpTrait> || - IS::type::Trait, LogTrait> || - IS::type::Trait, SquareRootTrait> || - IS::type::Trait, MinusUnaryTrait>; + typename ReRef::type::Trait; + requires IS::type::Trait, SinusTrait> || + IS::type::Trait, ASinusTrait> || + IS::type::Trait, SinusHTrait> || + IS::type::Trait, CosinusTrait> || + IS::type::Trait, ACosinusTrait> || + IS::type::Trait, CosinusHTrait> || + IS::type::Trait, TangensTrait> || + IS::type::Trait, ATangensTrait> || + IS::type::Trait, TangensHTrait> || + IS::type::Trait, ExpTrait> || + IS::type::Trait, LogTrait> || + IS::type::Trait, + SquareRootTrait> || + IS::type::Trait, MinusUnaryTrait>; }; template concept IsBinary = requires { - 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>; + 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>; }; template concept IsComparison = requires { - typename ReRef::type::Trait; - requires - 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, 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 @@ -119,7 +118,7 @@ concept IsOpVec = requires(T t) { }; template -concept IsVecRorCalc= requires(T t) { +concept IsVecRorCalc = requires(T t) { typename T::DType; requires IsOpVec || IsRBufferVec; }; @@ -127,14 +126,11 @@ concept IsVecRorCalc= requires(T t) { // Test Input class // =================================================================== // Vector -template -struct is_vec: std::false_type {}; +template struct is_vec : std::false_type {}; -template -struct is_vec> : std::true_type {}; +template struct is_vec> : std::true_type {}; -template -inline constexpr bool is_vec_v = is_vec ::value; +template inline constexpr bool is_vec_v = is_vec::value; template concept IsVec = is_vec_v; @@ -144,10 +140,8 @@ concept IsRVec = requires(T t) { requires IsVec && IsRBuffer; }; - // Binary -template -struct is_binary_operation : std::false_type {}; +template struct is_binary_operation : std::false_type {}; template struct is_binary_operation> @@ -159,8 +153,6 @@ 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/Traits.hpp b/inst/include/etr_bits/Core/Traits.hpp index d30a831..fdca3fc 100644 --- a/inst/include/etr_bits/Core/Traits.hpp +++ b/inst/include/etr_bits/Core/Traits.hpp @@ -13,13 +13,13 @@ struct ComparisonTrait { struct BaseStoreTrait {}; struct LBufferTrait {}; -struct RBufferTrait{}; +struct RBufferTrait {}; struct SubsetTrait {}; struct SubsetClassTrait {}; struct BorrowTrait {}; struct BorrowSEXPTrait {}; -struct BinaryTrait{}; -struct UnaryTrait{}; +struct BinaryTrait {}; +struct UnaryTrait {}; struct PlusTrait { template diff --git a/inst/include/etr_bits/Subsetting/LazySubsetting.hpp b/inst/include/etr_bits/Subsetting/LazySubsetting.hpp index c9e03d3..b8cd99b 100644 --- a/inst/include/etr_bits/Subsetting/LazySubsetting.hpp +++ b/inst/include/etr_bits/Subsetting/LazySubsetting.hpp @@ -25,14 +25,14 @@ void precalcVecBool(V &vec, Indices &ind, I *idx) { } template struct SubsetClassIterator { - const L &l; + L &l; const R &r; size_t index; - SubsetClassIterator(const L &l, const R &r, size_t index = 0) + SubsetClassIterator(L &l, const R &r, size_t index = 0) : l(l), r(r), index(index) {} - auto operator*() const { + auto &operator*() const { if constexpr (IsArithV) { return l[r]; } else if constexpr (!IsArithV) { @@ -50,12 +50,38 @@ template struct SubsetClassIterator { } }; +template struct SubsetClassConstantIterator { + L &l; + const R &r; + size_t index; + + SubsetClassConstantIterator(L &l, const R &r, size_t index = 0) + : l(l), r(r), index(index) {} + + auto operator*() const { + if constexpr (IsArithV) { + return l[r]; + } else if constexpr (!IsArithV) { + return l[r[index % r.size()] - 1]; + } + } + + SubsetClassConstantIterator &operator++() { + ++index; + return *this; + } + + bool operator!=(const SubsetClassConstantIterator &other) const { + return index != other.index; + } +}; + +// NOTE: Subset L values template struct SubsetClass { - using RetType = typename ExtractDataType::RetType; + using RetType = typename ReRef::type::RetType; using TypeTrait = Trait; - std::optional storedL; std::optional storedR; - const L &l; + L &l; const R &r; using typeTraitL = L; @@ -78,37 +104,106 @@ template struct SubsetClass { std::size_t nr() const { return calculateDim(); } // Constructor for lvalues (both `l_` and `r_`) - SubsetClass(const L &l_, const R &r_) : l(l_), r(r_) {} + SubsetClass(L &l_, R &r_) : l(l_), r(r_) {} + + // Constructor for lvalue `l_` and rvalue `r_` + SubsetClass(L &l_, R &&r_) : storedR(std::move(r_)), l(l_), r(*storedR) { + std::cout << "Constructor SubsetClass" << std::endl; + std::cout << r.size() << std::endl; + std::cout << storedR->size() << std::endl; + } + + template + SubsetClass(SubsetClass &other) + : l(other.l), r(other.r) {} + + auto &operator[](std::size_t i) { + if constexpr (IsArithV) { + return l[i]; + } else { + return l[r[i % l.size()] - 1]; + } + } + std::size_t size() const { + if constexpr (IsArithV) { + return l.size(); + } else { + std::cout << "size method SubsetClass" << std::endl; + std::cout << r.size() << std::endl; + std::cout << storedR->size() << std::endl; + return r.size(); + } + } + + void setMatrix(bool i, std::size_t nrow, std::size_t ncol) { + mp.setMatrix(i, nrow, ncol); + } + void setMatrix(MatrixParameter &mp_) { + mp.setMatrix(mp_.ismatrix, mp_.rows, mp_.cols); + } + void setMatrix(const MatrixParameter &mp_) { + mp.setMatrix(mp_.ismatrix, mp_.rows, mp_.cols); + } + auto begin() const { return SubsetClassIterator{l, r, 0}; } + auto end() const { return SubsetClassIterator{l, r, this->size()}; } +}; + +// NOTE: Subset R Value +template +struct SubsetClass { + using RetType = typename ExtractDataType::RetType; + using TypeTrait = Trait; + std::optional storedL; + std::optional storedR; + L &l; + const R &r; + + using typeTraitL = L; + using typeTraitR = R; + MatrixParameter mp; + + bool im() const { return l.im() || r.im(); } + std::size_t calculateDim() const { + if (l.im() && r.im()) + return (l.nr() > r.nr()) ? l.nr() : r.nr(); + if (!l.im() && r.im()) + return r.nr(); + if (l.im() && !r.im()) + return l.nr(); + ass<"Matrix calculation failed!">(false); + return 0; + } + + std::size_t nc() const { return calculateDim(); } + std::size_t nr() const { return calculateDim(); } // Constructor for rvalues (both `l_` and `r_`) SubsetClass(L &&l_, R &&r_) : storedL(std::move(l_)), storedR(std::move(r_)), l(*storedL), r(*storedR) {} - // Constructor for lvalue `l_` and rvalue `r_` - SubsetClass(const L &l_, R &&r_) - : storedR(std::move(r_)), l(l_), r(*storedR) {} - // Constructor for rvalue `l_` and lvalue `r_` SubsetClass(L &&l_, const R &r_) : storedL(std::move(l_)), l(*storedL), r(r_) {} - SubsetClass(const SubsetClass &other) : l(other.l), r(other.r) {} - // Move constructor - SubsetClass(const SubsetClass &&other) - : storedL(other.storedL ? std::move(other.storedL) : std::optional{}), - storedR(other.storedR ? std::move(other.storedR) : std::optional{}), - l(other.storedL.has_value() ? *storedL : other.l), - r(other.storedR.has_value() ? *storedR : other.r) {} template - SubsetClass(const SubsetClass &other) + SubsetClass(SubsetClass &other) : l(other.l), r(other.r) {} - auto operator[](std::size_t i) const { return l[r[i % l.size()] - 1]; } - // TODO: it is possible to use indices larger than length of l. It is safe - // but not the behaviour in R - std::size_t size() const { return r.size(); } - + const auto operator[](std::size_t i) { + if constexpr (IsArithV) { + return l[i]; + } else { + return l[r[i % l.size()] - 1]; + } + } + std::size_t size() const { + if constexpr (IsArithV) { + return l.size(); + } else { + return r.size(); + } + } void setMatrix(bool i, std::size_t nrow, std::size_t ncol) { mp.setMatrix(i, nrow, ncol); } @@ -118,53 +213,41 @@ template struct SubsetClass { void setMatrix(const MatrixParameter &mp_) { mp.setMatrix(mp_.ismatrix, mp_.rows, mp_.cols); } - auto begin() const { return SubsetClassIterator{l, r, 0}; } - auto end() const { return SubsetClassIterator{l, r, this->size()}; } + auto begin() const { return SubsetClassConstantIterator{l, r, 0}; } + auto end() const { + return SubsetClassConstantIterator{l, r, this->size()}; + } }; -// NOTE: the following subsetArithmetic, subsetBoolean, subsetVector and -// subsetSubset functions mean that a vector is subsetted by something which -// can be either a scalar (int or double), a bool, a vector or a SubsetClass -// (wrapped in a Vec). -template auto subsetArithmeticR(L &&l, R &&r) { +// NOTE: R = int | double +template inline auto &subsetArithmeticL(L &&l, R &&r) { using RetType = typename ExtractDataType>::RetType; if constexpr (IsFloatingPointV) { ass<"Negative indices are not supported">(r >= 0); - return static_cast(l[static_cast(std::floor(r)) - 1]); - } else if constexpr (IsBool) { - if (r) { - return l; - } else { - return Vec>(SI{0}); - } + return static_cast(l[static_cast(std::floor(r)) - 1]); } else if constexpr (IsIntegral) { ass<"Negative indices are not supported">(r >= 0); - return static_cast(l.d[r - 1]); + return static_cast(l.d[r - 1]); } else { ass<"Found unsupported arithmetic value">(false); } } -template auto subsetArithmeticL(L &&l, R &&r) { +template +inline const auto &subsetArithmeticR(L &&l, R &&r) { using RetType = typename ExtractDataType>::RetType; if constexpr (IsFloatingPointV) { ass<"Negative indices are not supported">(r >= 0); - return static_cast(l[static_cast(std::floor(r)) - 1]); - } else if constexpr (IsBool) { - if (r) { - return l; - } else { - return Vec(SI{0}); - } + return static_cast(l[static_cast(std::floor(r)) - 1]); } else if constexpr (IsIntegral) { ass<"Negative indices are not supported">(r >= 0); - return static_cast(l.d[r - 1]); + return static_cast(l.d[r - 1]); } else { ass<"Found unsupported arithmetic value">(false); } } -template auto subsetArithmetic(L &&l, R &&r) { +template inline auto &subsetArithmetic(L &&l, R &&r) { using RetType = typename ExtractDataType>::RetType; constexpr bool isLArgRvalue = IsRvalue; if constexpr (isLArgRvalue) { @@ -176,83 +259,65 @@ template auto subsetArithmetic(L &&l, R &&r) { } } -template auto subsetBoolean(L &&l, R &&r) { +template + requires((IsFloatingPointV || IsIntegral) && !IsBool) +inline auto &subset_test(L &&l, R &&r) { + static_assert(!IsArithV>, + "\n\nYou cannot subset a scalar value\n\n"); + constexpr bool isArithmeticL = IsArithV>; + constexpr bool isArithmeticR = IsArithV>; + using LType = ReRef; + using RType = ReRef; constexpr bool isLArgRvalue = IsRvalue; constexpr bool isRArgRvalue = IsRvalue; - using dataType = typename ExtractDataType>::RetType; - Indices ind; - precalcVecBool(l, ind, &r); - if constexpr (isLArgRvalue) { - return Vec>( - SubsetClass( - std::move(l.d), std::move(ind))); - } else { - return Vec>( - SubsetClass( - l.d, std::move(ind))); - } + return subsetArithmetic(std::forward(l), + std::forward>(r)); } -template auto subsetSubset(L &&l, R &&r) { +// NOTE: R = bool +template +inline auto subsetArithmeticBool(L &&l, R &&r) { + using RetType = typename ExtractDataType>::RetType; constexpr bool isLArgRvalue = IsRvalue; - constexpr bool isRArgRvalue = IsRvalue; - using dataType = typename ExtractDataType>::RetType; - Indices ind(r.size()); - for (std::size_t i = 0; i < r.size(); i++) { - ind[i] = r.d[i]; - } if constexpr (isLArgRvalue) { - return Vec>( - SubsetClass( - std::move(l.d), std::move(ind))); + SubsetClass sub(std::move(l.d), + r); + return Vec(std::move(sub)); } else { - return Vec>( - SubsetClass( - l.d, std::move(ind))); + SubsetClass sub(l.d, r); + return Vec(std::move(sub)); } } +template inline auto subset_test(L &&l, bool &&r) { + static_assert(!IsArithV>, + "\n\nYou cannot subset a scalar value\n\n"); + return subsetArithmeticBool(std::forward(l), + std::forward>(r)); +} -template auto subsetVector(L &&l, R &&r) { +// NOTE: R = Vec +template inline auto subset_test(L &&l, R &&r) { + static_assert(!IsArithV>, + "\n\nYou cannot subset a scalar value\n\n"); using RetType = typename ExtractDataType>::RetType; using SubsetType = SubsetClass; if constexpr (IsRvalue && IsRvalue) { - return subsetSubset(std::forward(l), std::forward(r)); - } else if constexpr (IsRvalue) { - return Vec(SubsetType(std::move(l.d), r.d)); - } else if constexpr (IsRvalue) { - return Vec(SubsetType(l.d, std::move(r.d))); - } else { - return Vec(SubsetType(l.d, r.d)); - } -} - -template auto subset_test(L &&l, R &&r) { - static_assert(!IsArithV>, - "\n\nYou cannot subset a scalar value\n\n"); - constexpr bool isArithmeticL = IsArithV>; - constexpr bool isArithmeticR = IsArithV>; - using LType = ReRef; - using RType = ReRef; - constexpr bool isLArgRvalue = IsRvalue; - constexpr bool isRArgRvalue = IsRvalue; - if constexpr (isArithmeticR) { - return subsetArithmetic(std::forward(l), - std::forward>(r)); + SubsetClass sub(std::move(l.d), + std::move(r.d)); + return Vec(std::move(sub)); + } else if constexpr (IsRvalue && !IsRvalue) { + SubsetClass sub(std::move(l.d), + r.d); + return Vec(std::move(sub)); + } else if constexpr (!IsRvalue && IsRvalue) { + return Vec>( + SubsetClass( + l.d, std::move(r.d))); } else { - using dataType = typename ExtractDataType>::RetType; - using dataTypeR = typename ExtractDataType>::RetType; - if constexpr (IS) { - return subsetBoolean(std::forward(l), - std::forward(r)); - } else { - return subsetVector(std::forward(l), - std::forward(r)); - } + SubsetClass sub(l.d, r.d); + return Vec(std::move(sub)); } } diff --git a/inst/include/etr_bits/Vector/VectorClass.hpp b/inst/include/etr_bits/Vector/VectorClass.hpp index d75b417..745e40e 100644 --- a/inst/include/etr_bits/Vector/VectorClass.hpp +++ b/inst/include/etr_bits/Vector/VectorClass.hpp @@ -15,7 +15,6 @@ template struct Vec { using DType = R; using RetType = typename ReRef::type::RetType; - template Vec(T2 n) = delete; #ifdef DERIV_ETR @@ -43,28 +42,28 @@ template struct Vec { // NOTE: Borrow template - requires IS> + requires IS> explicit Vec(const Borrow &&borrowed) : d(borrowed), deriv(borrowed.sz) { d.setMatrix(borrowed.mp); } template - requires IS> + requires IS> explicit Vec(const Borrow &borrowed) : d(borrowed), deriv(borrowed.sz) { d.setMatrix(borrowed.mp); } template - requires IS> + requires IS> explicit Vec(T *ptr, std::size_t s) : d(ptr, s), deriv(s) {} // NOTE: BorrowSEXP #ifdef STANDALONE_ETR #else template - requires IS> + requires IS> explicit Vec(SEXP &&inp) = delete; template - requires IS> + requires IS> explicit Vec(SEXP inp) : d(inp) { deriv.resize(d.sz); deriv.fill(0.0); @@ -82,35 +81,35 @@ template struct Vec { } // NOTE: Subset lazy template - requires IS + requires IS explicit Vec(const SubsetClass &&inp) - : d(inp), deriv(inp.size()) { + : d(inp), deriv(inp.size()) { d.setMatrix(inp.mp); } template - requires IS + requires IS explicit Vec(SubsetClass &inp) : d(inp), deriv(inp.size()) { d.setMatrix(inp.mp); } // NOTE: Binary operation template - requires IsBinaryOperation> + requires IsBinaryOperation> explicit Vec(const BinaryOperation &&inp) - : d(inp), deriv(inp.size()) { + : d(inp), deriv(inp.size()) { using TypeTrait = OperationTrait; d.setMatrix(inp.mp); } template // NOTE: only for comparison! + typename DetailTrait> // NOTE: only for comparison! explicit Vec(const BinaryOperation &&inp) - : d(inp), deriv(inp.size()) { + : d(inp), deriv(inp.size()) { using TypeTrait = OperationTrait; d.setMatrix(inp.mp); } template explicit Vec(BinaryOperation &inp) - : d(inp), deriv(inp.size()) { + : d(inp), deriv(inp.size()) { using TypeTrait = OperationTrait; d.setMatrix(inp.mp); } @@ -118,13 +117,13 @@ template struct Vec { // NOTE: Unary operation template explicit Vec(const UnaryOperation &&inp) - : d(inp), deriv(inp.size()) { + : d(inp), deriv(inp.size()) { using TypeTrait = OperationTrait; d.setMatrix(inp.mp); } template explicit Vec(UnaryOperation &inp) - : d(inp), deriv(inp.size()) { + : d(inp), deriv(inp.size()) { using TypeTrait = OperationTrait; d.setMatrix(inp.mp); } @@ -144,17 +143,17 @@ template struct Vec { // NOTE: matrix constructors explicit Vec(std::size_t rows, std::size_t cols) - : d(rows * cols), deriv(rows * 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(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> + requires IsVec> Vec(const Vec &&other_vec) { using TypeTrait = Trait2; using CaseTrait = Trait2; @@ -189,7 +188,7 @@ template struct Vec { // NOTE: other vector which is of type RVec and has different base type template - requires(IsRVec> && !IS) + requires(IsRVec> && !IS) Vec(const Vec &&other_vec) { using TypeTrait = Trait2; using CaseTrait = Trait2; @@ -224,7 +223,7 @@ template struct Vec { // NOTE: other vector which is of type RVec and with same base type template - requires(IsRVec> && IS) + requires(IsRVec> && IS) Vec(Vec &&other_vec) { using TypeTrait = Trait2; using CaseTrait = Trait2; @@ -267,7 +266,7 @@ template struct Vec { deriv.fill(0.0); } Vec(BaseType *ptr, std::size_t rows, std::size_t cols) - : d(rows * cols), deriv(rows * 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); @@ -293,28 +292,28 @@ template struct Vec { // NOTE: Borrow template - requires IS> + requires IS> explicit Vec(const Borrow &&borrowed) : d(borrowed) { d.setMatrix(borrowed.mp); } template - requires IS> + requires IS> explicit Vec(const Borrow &borrowed) : d(borrowed) { d.setMatrix(borrowed.mp); } template - requires IS> + requires IS> explicit Vec(T *ptr, std::size_t s) : d(ptr, s) {} // NOTE: BorrowSEXP #ifdef STANDALONE_ETR #else template - requires IS> + requires IS> explicit Vec(SEXP &&inp) = delete; template - requires IS> + requires IS> explicit Vec(SEXP inp) : d(inp) {} #endif @@ -327,12 +326,12 @@ template struct Vec { } // NOTE: Subset lazy template - requires IS + requires IS explicit Vec(const SubsetClass &&inp) : d(std::move(inp)) { d.setMatrix(inp.mp); } template - requires IS + requires IS explicit Vec(SubsetClass &inp) : d(std::move(inp)) { d.setMatrix(inp.mp); } @@ -375,13 +374,13 @@ template struct Vec { d.setMatrix(true, rows, cols); } explicit Vec(std::size_t rows, std::size_t cols, const double value) - : d(rows * cols) { + : 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> + requires IsVec> Vec(const Vec &&other_vec) { if constexpr (IsBorrow) { ass<"Sizes do not match">(d.sz <= @@ -410,7 +409,7 @@ template struct Vec { // NOTE: other vector which is of type RVec and has different base type template - requires(IsRVec> && !IS) + requires(IsRVec> && !IS) Vec(const Vec &&other_vec) { if constexpr (IsBorrow) { ass<"Sizes do not match">(d.sz <= other_vec.size()); @@ -465,7 +464,7 @@ template struct Vec { // NOTE: other vector which is of type RVec and with same base type template - requires(IsRVec> && IS) + requires(IsRVec> && IS) Vec(Vec &&other_vec) { if constexpr (IsBorrow) { ass<"Sizes do not match">(d.sz <= other_vec.size()); @@ -507,291 +506,296 @@ template struct Vec { } #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; - } + // 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"); + // Same Type + // --------------------------------------------------------------------- + if constexpr (is) { + if constexpr (IS::type::TypeTrait>) { + for (std::size_t i = 0; i < d.size(); i++) { + d[i] = inp; + } #ifdef DERIV_ETR - for (std::size_t i = 0; i < d.ind.size(); i++) { - deriv[i] = 0; - } + for (std::size_t i = 0; i < d.size(); i++) { + deriv[i] = 0; + } #endif - } else if constexpr (IsBorrow) { - d.sz = 1; - d[0] = inp; + } else if constexpr (IsBorrow) { + d.sz = 1; + d[0] = inp; #ifdef DERIV_ETR - deriv.resize(1); - deriv[0] = 0; + deriv.resize(1); + deriv[0] = 0; #endif - } else { - d.resize(1); - d[0] = inp; + } else { + d.resize(1); + d[0] = inp; #ifdef DERIV_ETR - deriv.resize(1); - deriv[0] = 0; + 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); } + return *this; + // Different Type + // --------------------------------------------------------------------- + } else { + if constexpr (IS::type::TypeTrait>) { + for (std::size_t i = 0; i < d.size(); i++) { + d[i] = static_cast(inp); + } #ifdef DERIV_ETR - for (std::size_t i = 0; i < d.ind.size(); i++) { - deriv[i] = 0; - } + for (std::size_t i = 0; i < d.size(); i++) { + deriv[i] = 0; + } #endif - } else if constexpr (IsBorrow) { - d.sz = 1; - d[0] = static_cast(inp); + } else if constexpr (IsBorrow) { + d.sz = 1; + d[0] = static_cast(inp); #ifdef DERIV_ETR - deriv.resize(1); - deriv[0] = 0; + deriv.resize(1); + deriv[0] = 0; #endif - } else { - d.resize(1); - d[0] = static_cast(inp); + } else { + d.resize(1); + d[0] = static_cast(inp); #ifdef DERIV_ETR - deriv.resize(1); - deriv[0] = 0; + deriv.resize(1); + deriv[0] = 0; #endif + } + return *this; } - 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"); + 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 = const Vec::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]); + using DataTypeOtherVec = const Vec::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]); + 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 (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()); } - } - 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? + // 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()); + 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; - } + deriv.resize(this->size()); + for (std::size_t i = 0; i < deriv.size(); i++) { + deriv[i] = 0; + } #endif - return *this; -} + 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"); + 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.d[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]); + 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.d[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 (IS::type::TypeTrait>) { + std::cout << "operator=" << std::endl; + // std::cout << d.size() << " " << otherVec.size() << std::endl; + ass<"number of items to replace is not a multiple of replacement length">( + otherVec.size() == d.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 (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.size(); i++) { + d[i % d.size()] = temp[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()); } - } - 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]; - // } - } + 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; -} + return *this; + } #ifdef STANDALONE_ETR #else -Vec &operator=(SEXP s) { - d.initSEXP(s); + Vec &operator=(SEXP s) { + d.initSEXP(s); #ifdef DERIV_ETR - deriv.resize(d.sz); - deriv.fill(0.0); + deriv.resize(d.sz); + deriv.fill(0.0); #endif - return *this; -} + return *this; + } #endif - - RetType &operator[](std::size_t idx) { return d[idx]; } RetType operator[](std::size_t idx) const { return d[idx]; } @@ -939,7 +943,6 @@ Vec &operator=(SEXP s) { return ret; } #endif - }; } // namespace etr