diff --git a/include/efp.hpp b/include/efp.hpp index 3ffd615..9bdf302 100644 --- a/include/efp.hpp +++ b/include/efp.hpp @@ -1,14 +1,13 @@ #ifndef EFP_HPP_ #define EFP_HPP_ -#include "prelude.hpp" - +#include "sequence.hpp" #include "enum_type.hpp" #include "maybe.hpp" -#include "sequence.hpp" +#include "prelude.hpp" #include "numeric.hpp" #include "scientific.hpp" -#include "c_utility.hpp" #include "cyclic.hpp" +#include "c_utility.hpp" #endif \ No newline at end of file diff --git a/include/prelude.hpp b/include/prelude.hpp index be97a97..8830aeb 100644 --- a/include/prelude.hpp +++ b/include/prelude.hpp @@ -1,5 +1,5 @@ -#ifndef CRTP_PRELUDE_HPP_ -#define CRTP_PRELUDE_HPP_ +#ifndef PRELUDE_HPP_ +#define PRELUDE_HPP_ #include #include @@ -265,7 +265,7 @@ namespace efp }; template - struct FromFunctionReturnImpl, F> + struct FromFunctionReturnImpl, F> { using Type = Sequence, n, n>; }; @@ -481,9 +481,9 @@ namespace efp template using TailReturn = EnableIf, Element>, - IsStaticLength::value ? A::ct_len - 1 : dyn, - IsStaticCapacity::value ? A::ct_cap - 1 : dyn>>; + SequenceRef, Element>, + IsStaticLength::value ? A::ct_len - 1 : dyn, + IsStaticCapacity::value ? A::ct_cap - 1 : dyn>>; // tail // ! Partial function. Application on empty list is abortion. @@ -531,9 +531,9 @@ namespace efp template using InitReturn = EnableIf, Element>, - IsStaticLength::value ? A::ct_len - 1 : dyn, - IsStaticCapacity::value ? A::ct_cap - 1 : dyn>>; + SequenceRef, Element>, + IsStaticLength::value ? A::ct_len - 1 : dyn, + IsStaticCapacity::value ? A::ct_cap - 1 : dyn>>; // init @@ -588,24 +588,31 @@ namespace efp return as[length(as) - 1]; } - // todo is_null + // is_null + + template + bool is_null(const Seq &as) + { + return length(as) == 0; + } // TakeReturnImpl + template struct TakeReturnImpl { }; template - struct TakeReturnImpl, A, is_const> + struct TakeReturnImpl, A, is_const> { using Type = Conditional< IsStaticLength::value, - SequenceView, Element>, bound_v(0, A::ct_len, n), bound_v(0, A::ct_len, n)>, + SequenceRef, Element>, bound_v(0, A::ct_len, n), bound_v(0, A::ct_len, n)>, Conditional< IsStaticCapacity::value, - SequenceView, Element>, dyn, A::ct_cap>, - SequenceView, Element>, dyn, dyn>>>; + SequenceRef, Element>, dyn, A::ct_cap>, + SequenceRef, Element>, dyn, dyn>>>; }; template @@ -613,8 +620,8 @@ namespace efp { using Type = Conditional< IsStaticCapacity::value, - SequenceView, Element>, dyn, A::ct_cap>, - SequenceView, Element>, dyn, dyn>>; + SequenceRef, Element>, dyn, A::ct_cap>, + SequenceRef, Element>, dyn, dyn>>; }; // TakeReturn @@ -660,15 +667,15 @@ namespace efp }; template - struct DropReturnImpl, A, is_const> + struct DropReturnImpl, A, is_const> { using Type = Conditional< IsStaticLength::value, - SequenceView, Element>, bound_v(0, A::ct_len, A::ct_len - n), bound_v(0, A::ct_len, A::ct_len - n)>, + SequenceRef, Element>, bound_v(0, A::ct_len, A::ct_len - n), bound_v(0, A::ct_len, A::ct_len - n)>, Conditional< IsStaticCapacity::value, - SequenceView, Element>, dyn, A::ct_cap>, - SequenceView, Element>, dyn, dyn>>>; + SequenceRef, Element>, dyn, A::ct_cap>, + SequenceRef, Element>, dyn, dyn>>>; }; template @@ -676,8 +683,8 @@ namespace efp { using Type = Conditional< IsStaticCapacity::value, - SequenceView, Element>, dyn, A::ct_cap>, - SequenceView, Element>, dyn, dyn>>; + SequenceRef, Element>, dyn, A::ct_cap>, + SequenceRef, Element>, dyn, dyn>>; }; // DropReturn @@ -719,6 +726,54 @@ namespace efp return result; } + // SliceReturn + + template + using SliceReturn = TakeReturn, is_const>; + + // slice + + // todo Optimization + template + auto slice(const S &start, const E &end, const Seq &as) + -> SliceReturn + { + // return take(end - start, drop(start, as)); + + const auto as_length = length(as); + const auto bounded_start = bound_v(0, as_length, start); + const auto bounded_end = bound_v(0, as_length, end); + + SliceReturn result{data(as) + bounded_start}; + + if (SliceReturn::ct_len == dyn) + { + result.resize(bounded_end - bounded_start); + } + + return result; + } + + template + auto slice(const S &start, const E &end, Seq &as) + -> SliceReturn + { + // return take(end - start, drop(start, as)); + + const auto as_length = length(as); + const auto bounded_start = bound_v(0, as_length, start); + const auto bounded_end = bound_v(0, as_length, end); + + SliceReturn result{data(as) + bounded_start}; + + if (SliceReturn::ct_len == dyn) + { + result.resize(bounded_end - bounded_start); + } + + return result; + } + // elem template diff --git a/include/sequence.hpp b/include/sequence.hpp index da10d63..69de642 100644 --- a/include/sequence.hpp +++ b/include/sequence.hpp @@ -1,5 +1,5 @@ -#ifndef CRTP_SEQUENCE_HPP_ -#define CRTP_SEQUENCE_HPP_ +#ifndef SEQUENCE_HPP_ +#define SEQUENCE_HPP_ // Curiously Recurring Template Pattern Sequence // Check validity on data store @@ -571,13 +571,13 @@ namespace efp // Should have all these three template parameter not to break static link template - class SequenceView + class SequenceRef { }; template - class SequenceView - : public SequenceBase> + class SequenceRef + : public SequenceBase> { public: using Element = A; @@ -587,17 +587,17 @@ namespace efp static_assert(ct_len >= -1, "ct_length must greater or equal than -1."); static_assert(ct_cap >= -1, "ct_capacity must greater or equal than -1."); - SequenceView() : data_{nullptr} {} - SequenceView(const SequenceView &); // Not emplemented by design for RVO, NRVO enforcement - SequenceView(SequenceView &&); // Not emplemented by design for RVO, NRVO enforcement - SequenceView(A *data) + SequenceRef() : data_{nullptr} {} + SequenceRef(const SequenceRef &); // Not emplemented by design for RVO, NRVO enforcement + SequenceRef(SequenceRef &&); // Not emplemented by design for RVO, NRVO enforcement + SequenceRef(A *data) : data_{data} {} - // SequenceView(const A (&c_array)[ct_len]) + // SequenceRef(const A (&c_array)[ct_len]) // : data_{c_array} {} - // SequenceView(const std::array &stl_array) + // SequenceRef(const std::array &stl_array) // : data_{stl_array.data()} {} - SequenceView &operator=(const SequenceView &other) + SequenceRef &operator=(const SequenceRef &other) { if (this != &other) { @@ -606,7 +606,7 @@ namespace efp return *this; } - SequenceView assign_impl(const SequenceView &other) + SequenceRef assign_impl(const SequenceRef &other) { if (this != &other) { @@ -625,7 +625,7 @@ namespace efp return data_[index]; } - bool operator==(const SequenceView &other) const + bool operator==(const SequenceRef &other) const { return data_ == other.data_; } @@ -696,11 +696,11 @@ namespace efp }; template - using ArrayView = EnableIf>; + using ArrayView = EnableIf>; template - class SequenceView - : public SequenceBase> + class SequenceRef + : public SequenceBase> { public: using Element = A; @@ -710,16 +710,16 @@ namespace efp static_assert(ct_len >= -1, "ct_length must greater or equal than -1."); static_assert(ct_cap >= -1, "ct_capacity must greater or equal than -1."); - SequenceView() : data_{nullptr}, length_{0} {} - SequenceView(const SequenceView &); // Not emplemented by design for RVO, NRVO enforcement - SequenceView(SequenceView &&); // Not emplemented by design for RVO, NRVO enforcement - SequenceView(A *data) : data_{data} {} - SequenceView(A *data, const int length) + SequenceRef() : data_{nullptr}, length_{0} {} + SequenceRef(const SequenceRef &); // Not emplemented by design for RVO, NRVO enforcement + SequenceRef(SequenceRef &&); // Not emplemented by design for RVO, NRVO enforcement + SequenceRef(A *data) : data_{data} {} + SequenceRef(A *data, const int length) : data_{data}, length_{length} { } - SequenceView &operator=(const SequenceView &other) + SequenceRef &operator=(const SequenceRef &other) { if (this != &other) { @@ -729,7 +729,7 @@ namespace efp return *this; } - SequenceView assign_impl(const SequenceView &other) + SequenceRef assign_impl(const SequenceRef &other) { if (this != &other) { @@ -749,7 +749,7 @@ namespace efp return data_[index]; } - bool operator==(const SequenceView &other) const + bool operator==(const SequenceRef &other) const { return (data_ == other.data_) && (length_ == other.length_); @@ -824,11 +824,11 @@ namespace efp }; template - using ArrVecView = EnableIf>; + using ArrVecView = EnableIf>; template - class SequenceView - : public SequenceBase> + class SequenceRef + : public SequenceBase> { public: using Element = A; @@ -838,18 +838,18 @@ namespace efp static_assert(ct_len >= -1, "ct_length must greater or equal than -1."); static_assert(ct_cap >= -1, "ct_capacity must greater or equal than -1."); - SequenceView() : data_{nullptr}, length_{0}, capacity_{0} {} - SequenceView(const SequenceView &); // Not emplemented by design for RVO, NRVO enforcement - SequenceView(SequenceView &&); // Not emplemented by design for RVO, NRVO enforcement - SequenceView(A *data) : data_{data} {} - SequenceView(A *data, const int length, const int capacity) + SequenceRef() : data_{nullptr}, length_{0}, capacity_{0} {} + SequenceRef(const SequenceRef &); // Not emplemented by design for RVO, NRVO enforcement + SequenceRef(SequenceRef &&); // Not emplemented by design for RVO, NRVO enforcement + SequenceRef(A *data) : data_{data} {} + SequenceRef(A *data, const int length, const int capacity) : data_{data}, length_{length}, capacity_{capacity} {} - SequenceView(const std::vector &stl_vector) + SequenceRef(const std::vector &stl_vector) : data_{stl_vector.data()}, length_(stl_vector.size()), capacity_(stl_vector.capacity()) {} - SequenceView &operator=(const SequenceView &other) + SequenceRef &operator=(const SequenceRef &other) { if (this != &other) { @@ -860,7 +860,7 @@ namespace efp return *this; } - SequenceView assign_impl(const SequenceView &other) + SequenceRef assign_impl(const SequenceRef &other) { if (this != &other) { @@ -881,7 +881,7 @@ namespace efp return data_[index]; } - bool operator==(const SequenceView &other) const + bool operator==(const SequenceRef &other) const { return (data_ == other.data_) && (length_ == other.length_) && @@ -963,10 +963,10 @@ namespace efp }; template - using VectorView = SequenceView; + using VectorView = SequenceRef; template - class SequenceTrait> + class SequenceTrait> { public: using Element = A; @@ -994,7 +994,7 @@ namespace efp } template - std::ostream &operator<<(std::ostream &os, const SequenceView &seq) + std::ostream &operator<<(std::ostream &os, const SequenceRef &seq) { os << "{ "; for (int i = 0; i < seq.size(); ++i) @@ -1149,6 +1149,11 @@ namespace efp return as.end(); } + // Int + + template + using Int = IntegralConst; + }; #endif \ No newline at end of file diff --git a/include/sfinae.hpp b/include/sfinae.hpp index 39d5371..0720b2f 100644 --- a/include/sfinae.hpp +++ b/include/sfinae.hpp @@ -289,29 +289,8 @@ namespace efp // template // using ReferenceRemoved = typename std::remove_reference::Type; - // CommonImpl - - // ! Deprecated - - // template - // using Common = typename std::common_type::Type; - - // IsIntegralConstant - - // template - // struct IsIntegralConstant : std::false_type - // { - // }; - - // template - // struct IsIntegralConstant> : std::true_type - // { - // }; - // IntegralConst - // ! Issue on (int, IntegralConst, -1); - template struct IntegralConst { @@ -323,6 +302,38 @@ namespace efp constexpr value_type operator()() const noexcept { return value; } // Function call operator }; + template + constexpr IntegralConst operator+( + IntegralConst, + IntegralConst) + { + return IntegralConst{}; + } + + template + constexpr IntegralConst operator-( + IntegralConst, + IntegralConst) + { + return IntegralConst{}; + } + + template + constexpr IntegralConst operator*( + IntegralConst, + IntegralConst) + { + return IntegralConst{}; + } + + template + constexpr IntegralConst operator/( + IntegralConst, + IntegralConst) + { + return IntegralConst{}; + } + // IsIntegralConst template @@ -546,7 +557,7 @@ namespace efp template using ReferenceRemoved = typename ReferenceRemovedImpl::Type; - // Commontype + // Common template struct CommonImpl diff --git a/test/prelude_test.hpp b/test/prelude_test.hpp index 65650cf..00f41bd 100644 --- a/test/prelude_test.hpp +++ b/test/prelude_test.hpp @@ -389,6 +389,27 @@ TEST_CASE("drop") } } +TEST_CASE("slice") +{ + SECTION("static") + { + const auto slice_ = slice(Int<1>{}, Int<3>{}, array_5); + CHECK(length(slice_) == 2); + CHECK(IsStaticLength::value); + CHECK(slice_[0] == 2.); + CHECK(slice_[1] == 3.); + } + + SECTION("dynamic") + { + const auto slice_ = slice(1, 3, array_5); + CHECK(IsSame::value); + CHECK(!IsStaticLength::value); + CHECK(slice_[0] == 2.); + CHECK(slice_[1] == 3.); + } +} + TEST_CASE("elem") { SECTION("Array")