Skip to content

Commit

Permalink
feat: Implement slice with test
Browse files Browse the repository at this point in the history
  • Loading branch information
cwahn committed Oct 1, 2023
1 parent 0332259 commit 2580264
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 88 deletions.
7 changes: 3 additions & 4 deletions include/efp.hpp
Original file line number Diff line number Diff line change
@@ -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
99 changes: 77 additions & 22 deletions include/prelude.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef CRTP_PRELUDE_HPP_
#define CRTP_PRELUDE_HPP_
#ifndef PRELUDE_HPP_
#define PRELUDE_HPP_

#include <array>
#include <vector>
Expand Down Expand Up @@ -265,7 +265,7 @@ namespace efp
};

template <int n, typename F>
struct FromFunctionReturnImpl<IntegralConst<int, n>, F>
struct FromFunctionReturnImpl<Int<n>, F>
{
using Type = Sequence<CallReturn<F, int>, n, n>;
};
Expand Down Expand Up @@ -481,9 +481,9 @@ namespace efp

template <typename A, bool is_const>
using TailReturn = EnableIf<A::ct_len != 0 && A::ct_cap != 0,
SequenceView<Conditional<is_const, const Element<A>, Element<A>>,
IsStaticLength<A>::value ? A::ct_len - 1 : dyn,
IsStaticCapacity<A>::value ? A::ct_cap - 1 : dyn>>;
SequenceRef<Conditional<is_const, const Element<A>, Element<A>>,
IsStaticLength<A>::value ? A::ct_len - 1 : dyn,
IsStaticCapacity<A>::value ? A::ct_cap - 1 : dyn>>;

// tail
// ! Partial function. Application on empty list is abortion.
Expand Down Expand Up @@ -531,9 +531,9 @@ namespace efp

template <typename A, bool is_const>
using InitReturn = EnableIf<A::ct_len != 0 && A::ct_cap != 0,
SequenceView<Conditional<is_const, const Element<A>, Element<A>>,
IsStaticLength<A>::value ? A::ct_len - 1 : dyn,
IsStaticCapacity<A>::value ? A::ct_cap - 1 : dyn>>;
SequenceRef<Conditional<is_const, const Element<A>, Element<A>>,
IsStaticLength<A>::value ? A::ct_len - 1 : dyn,
IsStaticCapacity<A>::value ? A::ct_cap - 1 : dyn>>;

// init

Expand Down Expand Up @@ -588,33 +588,40 @@ namespace efp
return as[length(as) - 1];
}

// todo is_null
// is_null

template <typename A>
bool is_null(const Seq<A> &as)
{
return length(as) == 0;
}

// TakeReturnImpl

template <typename N, typename A, bool is_const>
struct TakeReturnImpl
{
};

template <int n, typename A, bool is_const>
struct TakeReturnImpl<IntegralConst<int, n>, A, is_const>
struct TakeReturnImpl<Int<n>, A, is_const>
{
using Type = Conditional<
IsStaticLength<A>::value,
SequenceView<Conditional<is_const, const Element<A>, Element<A>>, bound_v(0, A::ct_len, n), bound_v(0, A::ct_len, n)>,
SequenceRef<Conditional<is_const, const Element<A>, Element<A>>, bound_v(0, A::ct_len, n), bound_v(0, A::ct_len, n)>,
Conditional<
IsStaticCapacity<A>::value,
SequenceView<Conditional<is_const, const Element<A>, Element<A>>, dyn, A::ct_cap>,
SequenceView<Conditional<is_const, const Element<A>, Element<A>>, dyn, dyn>>>;
SequenceRef<Conditional<is_const, const Element<A>, Element<A>>, dyn, A::ct_cap>,
SequenceRef<Conditional<is_const, const Element<A>, Element<A>>, dyn, dyn>>>;
};

template <typename A, bool is_const>
struct TakeReturnImpl<int, A, is_const>
{
using Type = Conditional<
IsStaticCapacity<A>::value,
SequenceView<Conditional<is_const, const Element<A>, Element<A>>, dyn, A::ct_cap>,
SequenceView<Conditional<is_const, const Element<A>, Element<A>>, dyn, dyn>>;
SequenceRef<Conditional<is_const, const Element<A>, Element<A>>, dyn, A::ct_cap>,
SequenceRef<Conditional<is_const, const Element<A>, Element<A>>, dyn, dyn>>;
};

// TakeReturn
Expand Down Expand Up @@ -660,24 +667,24 @@ namespace efp
};

template <int n, typename A, bool is_const>
struct DropReturnImpl<IntegralConst<int, n>, A, is_const>
struct DropReturnImpl<Int<n>, A, is_const>
{
using Type = Conditional<
IsStaticLength<A>::value,
SequenceView<Conditional<is_const, const Element<A>, Element<A>>, bound_v(0, A::ct_len, A::ct_len - n), bound_v(0, A::ct_len, A::ct_len - n)>,
SequenceRef<Conditional<is_const, const Element<A>, Element<A>>, bound_v(0, A::ct_len, A::ct_len - n), bound_v(0, A::ct_len, A::ct_len - n)>,
Conditional<
IsStaticCapacity<A>::value,
SequenceView<Conditional<is_const, const Element<A>, Element<A>>, dyn, A::ct_cap>,
SequenceView<Conditional<is_const, const Element<A>, Element<A>>, dyn, dyn>>>;
SequenceRef<Conditional<is_const, const Element<A>, Element<A>>, dyn, A::ct_cap>,
SequenceRef<Conditional<is_const, const Element<A>, Element<A>>, dyn, dyn>>>;
};

template <typename A, bool is_const>
struct DropReturnImpl<int, A, is_const>
{
using Type = Conditional<
IsStaticCapacity<A>::value,
SequenceView<Conditional<is_const, const Element<A>, Element<A>>, dyn, A::ct_cap>,
SequenceView<Conditional<is_const, const Element<A>, Element<A>>, dyn, dyn>>;
SequenceRef<Conditional<is_const, const Element<A>, Element<A>>, dyn, A::ct_cap>,
SequenceRef<Conditional<is_const, const Element<A>, Element<A>>, dyn, dyn>>;
};

// DropReturn
Expand Down Expand Up @@ -719,6 +726,54 @@ namespace efp
return result;
}

// SliceReturn

template <typename S, typename E, typename A, bool is_const>
using SliceReturn = TakeReturn<decltype(E{} - S{}), DropReturn<S, A, is_const>, is_const>;

// slice

// todo Optimization
template <typename S, typename E, typename A>
auto slice(const S &start, const E &end, const Seq<A> &as)
-> SliceReturn<S, E, A, true>
{
// 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<S, E, A, true> result{data(as) + bounded_start};

if (SliceReturn<S, E, A, true>::ct_len == dyn)
{
result.resize(bounded_end - bounded_start);
}

return result;
}

template <typename S, typename E, typename A>
auto slice(const S &start, const E &end, Seq<A> &as)
-> SliceReturn<S, E, A, false>
{
// 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<S, E, A, false> result{data(as) + bounded_start};

if (SliceReturn<S, E, A, false>::ct_len == dyn)
{
result.resize(bounded_end - bounded_start);
}

return result;
}

// elem

template <typename A>
Expand Down
Loading

0 comments on commit 2580264

Please sign in to comment.